化学离子平衡作业偷懒神器

下一次加入沉淀平衡

这一段放到K.dat中,有需要自己添加

1e-14
4
1 CH3COOH 1.74e-5 CH3COO-
2 H2CO3 4.2e-7 HCO3- 5.6e-11 CO3--
2 H2S 1.3e-7 HS- 7.1e-15 S--
1 HCl 1e100 Cl-
3
1 NH3_H2O 1.78e-5 NH4+
3 Fe(OH)3 3.16e-9 Fe(OH)2- 5.01e-10 Fe(OH)-- 1.35e-12 Fe---
1 NaOH 1e100 Na+

以下为main.cpp

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-14;
double Kacid[110][5], Kbase[110][5];
int Na, Nb;
int Tacid[110], Tbase[110];

double Cacid[110][5], Cbase[110][5];
double CH, COH;
double Kw; // the ionic product of water
string nameAcid[110][5];
string nameBase[110][5];

void readData(){
	ifstream in("K.dat");
	in >> Kw;
	in >> Na;
	for (int i=1;i<=Na;i++){
		in >> Tacid[i];
		for (int j=1;j<=Tacid[i];j++){
			in >> nameAcid[i][j];
			in >> Kacid[i][j];
		}
		in >> nameAcid[i][Tacid[i]+1];
	}
	in >> Nb;
	for (int i=1;i<=Nb;i++){
		in >> Tbase[i];
		for (int j=1;j<=Tbase[i];j++){
			in >> nameBase[i][j];
			in >> Kbase[i][j];
		}
		in >> nameBase[i][Tbase[i]+1];
	}
	in.close();
}

double Solve(double &C1, double &C2, double &C3, double &C4, double K){
	if (K > 1e30){
		double T = min(C1, C2);
		C3 += T;
		C4 += T;
		C1 -= T;
		C2 -= T;
		return 0;
	}
	else if (K < 1e-30){
		double T = min(C3, C4);
		C3 -= T;
		C4 -= T;
		C1 += T;
		C2 += T;
		return 0;
	}
	double A = K-1;
	double B = -K*(C1+C2)-(C3+C4);
	double C = K*C1*C2 - C3*C4;
//	cout << A << ' ' << B << ' ' << C << endl;
	assert(B*B - 4 * A * C + eps >= 0);
	double X1 = (-B + sqrt(B*B-4*A*C)) / 2 / A;
	double X2 = (-B - sqrt(B*B-4*A*C)) / 2 / A;
	if (abs(X1) < eps && abs(X2) < eps) return 0;
//	cout << A << ' ' << B << ' ' << C << ' ' << X1 << ' ' << X2 << ' ' << K << endl;
	if (X1 < min(C1,C2) + eps && -X1 < min(C3,C4) + eps) {
		C1 -= X1; C2 -= X1; C3 += X1; C4 += X1;
		return X1;
	}
	if (X2 < min(C1,C2) + eps && -X2 < min(C3,C4) + eps) {
		C1 -= X2; C2 -= X2; C3 += X2; C4 += X2;
		return X2;
	}
	assert(0);
	return 0;
}

double Solve(double &C1, double &C2, double &C3, double K){
	if (K > 1e30){
		double T = C1;
		C3 += T;
		C1 -= T;
		C2 += T;
		return 0;
	}
	else if (K < 1e-30){
		double T = min(C3, C2);
		C1 += T;
		C2 -= T;
		C3 -= T;
		return 0;
	}
	double A = 1;
	double B = C2+C3+K*C1;
	double C = C2*C3-K*C1;
	assert(B*B - 4 * A * C + eps >= 0);
	double X1 = (-B + sqrt(B*B-4*A*C)) / 2 / A;
	double X2 = (-B - sqrt(B*B-4*A*C)) / 2 / A;
//	cout << X1 << ' ' << X2 << ' ' << K << endl;
	if (abs(X1) < eps && abs(X2) < eps) return 0;
	if (X1 < C1 + eps && -X1 < min(C2,C3) + eps) {
		C1 -= X1; C2 += X1; C3 += X1;
		return X1;
	}
	if (X2 < C1 + eps && -X2 < min(C2,C3) + eps) {
		C1 -= X2; C2 += X2; C3 += X2;
		return X2;
	}
	assert(0);
	return 0;
}

double SolveWater(){
	double A = 1;
	double B = -CH - COH;
	double C = CH * COH - Kw;
 // A = 1 B = -([H] + [OH]) C = [H][OH]-Kw;
	assert(B*B - 4 * A * C >= 0);
	double X1 = (-B + sqrt(B*B-4*A*C)) / 2 / A;
	double X2 = (-B - sqrt(B*B-4*A*C)) / 2 / A;
	if (X1 < min(CH,COH) + eps) {
		CH -= X1; COH -= X1;
		return X1;
	}
	if (X2 < min(CH,COH) + eps) {
		CH -= X2; COH -= X2;
		return X2;
	}
	assert(0);
	return 0;
}

void calc(){
	/* Find the reaction that can be do max*/
//	int Ka = 1, Kal = 1, Kb = 1, Kbl = 1;
//	double val = 0;
	for (int i=1;i<=Na;i++){
		for (int j=1;j<=Tacid[i];j++){
			for (int k=1;k<=Nb;k++){
				for (int l=1;l<=Tbase[k];l++){
						double K = Kacid[i][j] * Kbase[k][l] / Kw;
//						cout << Cacid[i][j] << ' ' << Cbase[k][l] << endl;
						Solve(Cacid[i][j], Cbase[k][l], Cacid[i][j+1], Cbase[k][l+1], K);
				}
			}
		}
	}
	
	for (int i=1;i<=Na;i++){
		for (int j=1;j<=Tacid[i];j++){
			double K = Kacid[i][j];
			Solve(Cacid[i][j], Cacid[i][j+1], CH, K);
		}
	}

	for (int i=1;i<=Nb;i++){
		for (int j=1;j<=Tbase[i];j++){
			double K = Kbase[i][j];
			Solve(Cbase[i][j], Cbase[i][j+1], COH, K);
		}
	}
	
	SolveWater();

}
/* 
 HA == A- + H+ Ka
 BOH == B+ + OH- Kb
 H+ + OH- == H2O 1/Kw
 HA + BOH == AB + H2O 
 [A-][B+]   [A-][H+][B+][OH-]
 -------- = ----------------- = Ka * Kb / Kw
  [AB]         [AB][H2O]   
  Sol.
  HA + BOH == A- + B+ + H2O K
  C1   C2     C3   C4
  (C3+x * C4+x) / (C1-x * C2-x) == K
  K(C1C2 - (C1+C2)x + x^2) == C3C4 + (C3+C4)x + x^2
  --> A = (K-1) B = -K*(C1+C2)-(C3+C4) C = KC1C2 - C3C4

  --------------------------------------------------------

  HA == A- + H+ Ka
  C1    C2   C3
   ([A-]+x)([H+]+x)
  ------------------ = K
         [HA]-x
  
  --> A = 1 B = C2+C3+K*C1 C = C2*C3-K*C1

  --------------------------------------------------------

  [H] * [OH] = Kw;
  ([H]-x) * ([OH]-x) = Kw;
  A = 1 B = -([H] + [OH]) C = [H][OH]-Kw;
*/
int main(){
	readData();
	int n;
	int T = 10000;
	Cacid[1][1] = 0.1;
	Cacid[1][2] = 0.1;
	Cbase[3][2] = 0.2;
	while (T--) calc();
	cout << "[H] = " << CH << endl;
	cout << "[OH] = " << COH << endl;
	cout << "pH = " << -log10(CH) << endl;
	cout << "Acid:" << endl;
	for (int i=1;i<=Na;i++){
		for (int j=1;j<=Tacid[i]+1;j++)
			cout << "[" << nameAcid[i][j] << "] = " << Cacid[i][j] << ' ';
		cout << endl;
	}
	cout << "Base" << endl;
	for (int i=1;i<=Nb;i++){
		for (int j=1;j<=Tbase[i]+1;j++)
			cout << "[" << nameBase[i][j] << "] = " << Cbase[i][j] << ' ';
		cout << endl;
	}
}

示例:
0.1mol/L CH3COOH 与 0.1mol/L CH3COONa混,最后pH值

	Cacid[1][1] = 0.1;
	Cacid[1][2] = 0.1;
	Cbase[3][2] = 0.1;

Solution:

[H] = 1.73939e-05
[OH] = 5.74913e-10
pH = 4.7596
Acid:
[CH3COOH] = 0.0999826 [CH3COO-] = 0.100017
[H2CO3] = 0 [HCO3-] = 0 [CO3--] = 0
[H2S] = 0 [HS-] = 0 [S--] = 0
[HCl] = 0 [Cl-] = 0
Base
[NH3_H2O] = 0 [NH4+] = 0
[Fe(OH)3] = 0 [Fe(OH)2-] = 0 [Fe(OH)--] = 0 [Fe---] = 0
[NaOH] = 0 [Na+] = 0.1

示例:
0.01mol/L CH3COOH 与 0.40mol/L CH3COONa混,最后pH值

	Cacid[1][1] = 0.01;
	Cacid[1][2] = 0.4;
	Cbase[3][2] = 0.4;

Solution:

[H] = 4.34982e-07
[OH] = 2.29895e-08
pH = 6.36153
Acid:
[CH3COOH] = 0.00999959 [CH3COO-] = 0.4
[H2CO3] = 0 [HCO3-] = 0 [CO3--] = 0
[H2S] = 0 [HS-] = 0 [S--] = 0
[HCl] = 0 [Cl-] = 0
Base
[NH3_H2O] = 0 [NH4+] = 0
[Fe(OH)3] = 0 [Fe(OH)2-] = 0 [Fe(OH)--] = 0 [Fe---] = 0
[NaOH] = 0 [Na+] = 0.4
posted @ 2020-11-22 21:53  dgklr  阅读(119)  评论(0编辑  收藏  举报