Алгоритм определения порядка химической реакции и константы скорости химической реакции.
Уравнение химической реакции дано в общем виде для реакции разложения: 3А 2В+С+5D. Алгоритм для определения константы скорости реакции представлен на рисунке 1.
Рисунок 1 – Алгоритм определения константы скорости реакции
Алгоритм позволяет на основании исходных данных определить k – константы скорости реакции, n – порядок реакции, r – коэффициент корреляции и d – дисперсии. Исходными данными являются:
- изменение концентрации исходного компонента СА(t) во времени,
- начальные концентрации компонентов СВ CC и CD,
- количество экспериментальных точек N.
Описание пользовательского интерфейса.
Программа состоит из двух форм (окон), представленных на рисунках 2 и 3 соответственно и позволяющих вводить начальные данные и отображать результаты расчета. Программа включает пять исходных файлов программы: Project1.cpp, Unit1.h, Unit1.cpp, Unit2.h, Unit2.cpp. Ниже приведен состав файлов с подробными комментариями.
Графический интерфейс включает следующие классы визуальных компонентов: формы TForm, изображения TImage, панели TPanel, группы элементов TGroupBox, метки TLabel, однострочный редактор текста с меткой TLabeledEdit, график TChart, кнопки TButton, компонент для ввода и изменения числовых значений TUpDown, таблица TStringGrid, и.т.д.
Проверка адекватности математической модели кинетики.
Полученное значение коэффициента корреляции r = 0,873 говорит о том, что связь между экспериментальными данными и расчетами, выполненными в математической модели существенная.
Полученное значение дисперсии d = 0,8265 – невелико что также свидетельствует о малом разбросе данных, полученных при использовании математической модели, относительно данных, полученных в результате эксперимента.
Из выше сказанного можно сделать вывод что математическая модель может быть использована для определения константы скорости химической реакции.
Примеры тестирования работоспособности программного обеспечения.
Тестирование разработанного в среде C++ Builder программного обеспечения проводилось при входных данных, которые были определены ранее.
Рисунок 2 – Форма ввода исходных данных, отображения экспериментальных значений и расчетных кривых концентраций
Рисунок 3 – Форма отображения результатов расчета
Результаты расчета:
Порядок реакции n = 1
Константа скорости реакции k = 0,32 1/c
Дисперсия d = 0,8265 (моль / л)2
Коэффициент корреляции r = 0,873
Заключение
В ходе выполнения курсового проекта было создано прикладное программное обеспечение позволяющего определять порядок химической реакции, константу скорости реакции, а также проводить статистический анализ результатов.
Был разработан алгоритм, который позволяет на основании исходных данных определить k – константы скорости реакции, n – порядок реакции, r – коэффициент корреляции и d – дисперсии. Исходными данными являются:
- изменение концентрации исходного компонента СА(t) во времени,
- начальные концентрации компонентов СВ CC и CD,
- количество экспериментальных точек N.
Для реализации алгоритма решения обратной задачи кинетики было разработано программное обеспечение, включающее графический пользовательский интерфейс. В качестве интегрированной среды разработки программного обеспечения (Integrated Development Environment, IDE) используется С++ Builder.
Программа состоит из двух форм, позволяющих вводить начальные данные и отображать результаты расчета. Программа включает пять исходных файлов программы: Project1.cpp, Unit1.h, Unit1.cpp, Unit2.h, Unit2.cpp.
Было проведено тестирование работоспособности программного продукта и проведена оценка адекватности математической модели по полученным значениям дисперсии и корреляции. Было определено что математическая модель может быть использована для определения константы скорости химической реакции.
Список использованной литературы.
1. Архангельский, А. Я. Программирование в C++Builder 6 и 2006: разработка программ для Windows: методические и справочные мате-риалы по C++Builder] / А. Я. Архангельский, М. А. Тагин. — Москва: БИНОМ, 2007. — 1181 с.
2. Страуструп, Бьерн. Язык программирования C++ / Бьерн Страуструп; Пер. с англ. С. Анисимова, М. Кононова; Под ред. Ф. Андреева, А. Ушакова. — Спец. изд. — М.: Бином; СПб.: Нев. диалект, 2001. — 1098 с.
3. Эккель, Брюс. Философия C++: Практ. программирование / Брюс Эккель, Чак Эллисон; [Пер. с англ. Е. Матвеев]. — М.: Питер, 2004. — 608 с.
4. Липпман, Стенли Б. Язык программирования С++: вводный курс / Стенли Б. Липпман, Жози Лажойе, Барбара Му; [пер. с англ. и ред. В. А. Коваленко]. — 4-е изд. — М.: Вильямс, 2007. — 889 с.
5. Астахова, И. Ф. Язык C++ / И. Ф. Астахова, С. В. Власов, В. В. Фертиков, А. В. Ларин. — Минск: Новое знание, 2003. — 200 с.
6. Иванова, Г. С. Основы программирования / Г. С. Иванова. — Изд. 4-е, стер. — М.: Изд-во МГТУ, 2007. — 415 с.
7. Иванова, Г. С. Объектно-ориентированное программирование / Г. С. Иванова, Т. Н. Ничушкина, Е. К. Пугачев; под ред. Г. С. Ивановой. -Изд. 3-е, стер. — М.: Изд-во МГТУ, 2007. — 366 с.
8. Чистякова, Т. Б. Программирование на языках высокого уровня. Базовый курс: учебное пособие для студентов заочной формы обучения/ Т. Б. Чистякова, Р. В. Антипин, И. В. Новожилова. — СПб.: СПбГТИ (ТУ), 2008. — 227 с.
9. Чистякова, Т. Б. Синтез и анализ математических моделей кинетики-химических реакций: учебное пособие / Т. Б. Чистякова, Л. В. Гольцева, А. М. Островская, Ю. В. Островский. — СПб.: СПбГТИ (ТУ), 2002. — 70 с.
10. Гартман, Т. Н. Основы компьютерного моделирования химико-технологических процессов: учебное пособие / Т. Н. Гартман, Д. В. Клушин. — Москва: Академкнига, 2008. — 415 с.
Приложение А
Unit1.cpp
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
#include "math.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//Задание загаловка таблицы
StringGrid1->Cells[0][0] = "C";
StringGrid1->Cells[1][0] = "t";
float qqq[6]={0,1,2,3,4,5};
float rrr[6]={5,4,3,2,1,0.5};
for(int i=1;i<6+1;i++)
{
StringGrid1->Cells[1][i]=qqq[i-1];
StringGrid1->Cells[0][i]=rrr[i-1];
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::UpDown1Click(TObject *Sender, TUDBtnType Button)
{ //опред. обработчика для изменения кол-ва строк таблицы
StringGrid1->RowCount = UpDown1->Position + 1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{ //Инициализация переменных для решения задачи кинетики
d = 0.0;
int i, reg_up(0), reg_down(0);
double *y, *x, s1(UpDown1->Position - 1),
s2(0.0), s3(0.0), s4(0.0), s5(0.0), s6(0.0), ca, cb, cc,cd, t;
//Очистка графиков после предыдущего расчета
Series1->Clear();
Series2->Clear();
Series3->Clear();
Series4->Clear();
Series5->Clear();
try
{
//создание в динамичесой памят массива для хранения экспериментальных данных
y = new double[UpDown1->Position - 1];
x = new double[UpDown1->Position - 1];
if(!y || !x) throw "НЕТ свободной памяти";
//Задание начальных значений концентраций
ca = StringGrid1->Cells[0][1].ToDouble();
cb = LabeledEdit1->Text.ToDouble();
cc = LabeledEdit2->Text.ToDouble();
cd= LabeledEdit4->Text.ToDouble();
//Проверка входных данных на допустимость значений
if(!ca || cb < 0.0 || cc < 0.0 || cd < 0.0)
throw "Начальные концентрации компонентов должны быть больше 0";
for(i = 0; i < UpDown1->Position - 1; i++)
{
if(StringGrid1->Cells[0][i + 1].ToDouble() > StringGrid1->Cells[0][i + 2].ToDouble())
reg_down++;
else reg_up++;
if(StringGrid1->Cells[0][i + 1].ToDouble() == StringGrid1->Cells[0][i + 2].ToDouble())
throw "Концентрация в соседних точках должна быть различна";
if(StringGrid1->Cells[1][i + 1].ToDouble() >= StringGrid1->Cells[1][i + 2].ToDouble())
throw "Нарушение последовательности ввода времени";
if(StringGrid1->Cells[1][i+1].ToDouble()< 0||StringGrid1->Cells[0][i + 1].ToDouble()<0)
throw "Время и концентрация не могут быть отрицательными";
}
//Расчет значений локальных переменных, необходимых для решения задачи
double t1,t2,t3,t4,t5,t6,b1,b0;
for(i = 0; i < UpDown1->Position - 1; i++)
{
t1= StringGrid1->Cells[0][i + 2].ToDouble();
t2= StringGrid1->Cells[0][i + 1].ToDouble();
t3= StringGrid1->Cells[1][i + 2].ToDouble();
t4=StringGrid1->Cells[1][i + 1].ToDouble();
t5=t1-t2;
t6=t3-t4;
y[i] = log(fabs(t5) /t6);
x[i] = log(StringGrid1->Cells[0][i + 1].ToDouble());
s2 += x[i];
s3 += y[i];
s4 += x[i] * x[i];
s5 += x[i] * y[i];
s6 += y[i] * y[i];
}
//Расчет константы скорости реакции, порядка реакции, коэффициента корреляции
k = exp((s3 * s4 - s2 * s5) / (s1 * s4 - s2 * s2));
n = (s1 * s5 - s2 * s3) / (s1 * s4 - s2 * s2);
r = (s1 * s5 - s2 * s3) / sqrt((s1 * s4 - s2 * s2) * (s1 * s6 - s3 * s3));
//Построение графиков и расчет концентраций компонентов реакции
for(int i = 1; i <= UpDown1->Position; i++)
{
Series1->AddXY(StringGrid1->Cells[1][i].ToDouble(),StringGrid1->Cells[0][i].ToDouble());
if(ca < 0) throw "Модель невозможно описать линейной регрессией";
if(i == 1)
{
Series2->AddXY(StringGrid1->Cells[1][i].ToDouble(), ca );
Series3->AddXY(StringGrid1->Cells[1][i].ToDouble(), cb );
Series4->AddXY(StringGrid1->Cells[1][i].ToDouble(), cc );
Series5->AddXY(StringGrid1->Cells[1][i].ToDouble(), cd );
}
else
{
t = StringGrid1->Cells[1][i].ToDouble() - StringGrid1->Cells[1][i - 1].ToDouble();
Series3->AddXY(StringGrid1->Cells[1][i].ToDouble(), cb = cb + k *pow(ca, n) * t*2/3);
Series4->AddXY(StringGrid1->Cells[1][i].ToDouble(), cc = cc + k * pow(ca, n)*t/3);
Series5->AddXY(StringGrid1->Cells[1][i].ToDouble(), cd = cd + k * pow(ca, n)*t*5/3);
if(reg_down > reg_up)
Series2->AddXY(StringGrid1->Cells[1][i].ToDouble(), ca =ca-k*pow(ca, n) * t);
else
Series2->AddXY(StringGrid1->Cells[1][i].ToDouble(), ca =ca+k*pow(ca, n) * t);
}
//расчет дисперсии
d += pow(StringGrid1->Cells[0][i].ToDouble() - ca, 2);
}
//Создание формы отображения результатов
Application->CreateForm(__classid(TForm2), &Form2);
//Отображение формы
Form2->ShowModal();
delete[]y;
delete[]x;
}
catch(char*str)
{
Series1->Clear();
Series2->Clear();
Series3->Clear();
Series4->Clear();
Series5->Clear();
// Вывод сообщения об ошибке
Application->MessageBox(str, "Ошибка", MB_ICONERROR | MB_OK);
}
catch(EConvertError&)
{
// ?Вывод сообщения об ошибке
Application->MessageBox("Не правильный тип данных", "Ошибка",
MB_ICONERROR | MB_OK);
delete[]y;
delete[]x;
}
catch(...)
{
//Вывод сообщения об ошибке
Application->MessageBox("НЕ известная ошибка", "Ошибка",
MB_ICONERROR | MB_OK);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//---------------------------------------------------------------------------
Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Chart.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
#include <TeEngine.hpp>
#include <TeeProcs.hpp>
#include <Series.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TPanel *Panel1;
TGroupBox *GroupBox1;
TLabeledEdit *LabeledEdit1;
TLabeledEdit *LabeledEdit2;
TChart *Chart1;
TUpDown *UpDown1;
TLabeledEdit *LabeledEdit3;
TStringGrid *StringGrid1;
TButton *Button1;
TButton *Button2;
TPointSeries *Series1;
TLabeledEdit *LabeledEdit4;
TLineSeries *Series5;
TLineSeries *Series4;
TLineSeries *Series3;
TLineSeries *Series2;
TPointSeries *Series6;
void __fastcall FormCreate(TObject *Sender);
void __fastcall UpDown1Click(TObject *Sender, TUDBtnType Button);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
double k, n, d, r;
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit2.cpp
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
LabeledEdit2->Text = FloatToStrF(Form1->n, ffGeneral, 4, 4);
LabeledEdit3->Text = FloatToStrF(Form1->k, ffGeneral, 4, 4);
LabeledEdit1->Text = FloatToStrF(Form1->d, ffGeneral, 4, 4);
LabeledEdit4->Text = FloatToStrF(Form1->r, ffGeneral, 4, 4);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
Form2->Close();
}
Unit2.h
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published: // IDE-managed Components
TGroupBox *GroupBox1;
TLabeledEdit *LabeledEdit1;
TLabeledEdit *LabeledEdit2;
TLabeledEdit *LabeledEdit3;
TLabeledEdit *LabeledEdit4;
TButton *Button1;
void __fastcall FormShow(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif
Project1.cpp
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
USEFORM("Unit2.cpp", Form2);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->CreateForm(__classid(TForm2), &Form2);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}