Разработка программы расчёта величины pH водного раствора отмывочной композиции, включающей ДТПК или её натриевые




Соли с различной степенью замещения и щавелевую кислоту

 

Создание компьютерной программы позволяет определять текущие (мгновенные) параметры водной среды, что необходимо для разработки программного обеспечения автоматизации процесса химической очистки теплоэнергетического оборудования.

Программа расчёта составлена на языке программирования «Python». В ней жирным шрифтом выделены операторы, выполняемые компьютером для проведения расчётов и вывода результатов на экран монитора, а весь остальной текст – это пояснения к программе и рекомендации по её составлению.

Первая строка задаёт язык программирования «Python», вторая определяет кодировку файла – «utf-8» (это необходимо для адекватного восприятия файла в операционной среде Windows, так как по умолчанию задавалась бы другая кодировка, неподходящая для данного случая).

 

#!/usr/bin/env python

# -*- coding: utf-8 -*-

 

Следующая строка подключает библиотеку математических функций, которые будут использоваться в программе расчёта.

 

Import math

 

Далее идёт первая часть программы расчёта, в которой задаются исходные данные – в зависимости от рассматриваемого варианта задачи. Задание на расчёт состоит из двух частей, которые будут именоваться как «Вариант 1» и «Вариант 2».

Вариант 1

Определение величины pH водных монорастворов ДТПК или её натриевых солей с различной степенью замещения C (по натрию):

а) при 6 значениях концентрации реагента – 10–7, 10–6, 10–5, 10–4, 10–3 и 10–2 М (моль/л);

б) для каждой из этих 6 концентраций – при 11 значениях C (от 0 до 5 с шагом 0,5).

Таким образом, решение задачи по первому варианту предполагает нахождение 66 значений pH.

Вариант 2

Определение величины pH бинарных (двухкомпонентных) водных растворов, содержащих композицию «ДТПК (или её натриевая соль) + ЩК»:

а) при 5 соотношениях концентраций двух вышеназванных компонентов, г/л – 10 и 0; 7,5 и 2,5; 5 и 5; 2,5 и 7,5; 0 и 10;

б) для каждого из этих 5 бинарных растворов – при 11 значениях C (от 0 до 5 с шагом 0,5).

Следовательно, решение задачи по второму варианту предполагает нахождение 55 значений pH.

 

Приступаем к вводу исходных данных, причём совместно для обоих вариантов задачи.

Концентрации компонентов раствора должны фигурировать во всех вычислениях в единицах «М» (моль/л), в то время как во втором варианте задачи концентрации заданы в единицах «г/л». Отсюда следует, что для проведения расчётов необходимо ввести в качестве исходных данных молекулярные массы ДТПК и ЩК.

Кроме того, для натриевых солей ДТПК задание величины C означает, что в исходной молекуле ДТПК C ионов водорода замещаются на C ионов натрия (в среднем по всему раствору). Это требует ввода в качестве исходных данных также атомных масс водорода и натрия.

Вводим численные значения молекулярных масс ДТПК или её натриевых солей – MDTPK, г/моль. Слово «default» означает, что это начальное значение вводимой величины MDTPK, которое будет использовано для всех растворов со значением C, равным 0, то есть для растворов с участием самόй ДТПК, а не её натриевых солей. Для остальных растворов, когда C не равно 0, величина MDTPK станет переменной и будет вычисляться отдельно для каждого из «(66 – 6) + (55 – 5) = 110» растворов. При этом атомные массы водорода и натрия (1,01 и 22,99 г/моль соответственно) вводить здесь не будем, так как эти значения можно включить непосредственно в выражения для расчёта молекулярных масс натриевых солей ДТПК.

 

MDTPK_default=393.35

 

Вводим численное значение молекулярной массы ЩК – MSK, г/моль.

MSK=90.04

Вводим численные значения отрицательных десятичных логарифмов констант диссоциации ДТПК, приведенных к нулевой ионной силе раствора:

 

а) для первой ступени диссоциации

 

pk11=11.55

 

б) сумма отрицательных десятичных логарифмов констант диссоциации по первой и второй ступеням

pk12=20.96

 

в) сумма отрицательных десятичных логарифмов констант диссоциации по первой, второй и третьей ступеням

pk13=25.90

 

г) сумма отрицательных десятичных логарифмов констант диссоциации по первой, второй, третьей и четвёртой ступеням

pk14=28.99

 

д) сумма отрицательных десятичных логарифмов констант диссоциации по всем пяти ступеням

pk15=31.03

 

Вводим численные значения отрицательных десятичных логарифмов констант диссоциации ЩК (в таблице 2 они даны при нулевой ионной силе раствора):

 

а) для первой ступени диссоциации

 

pk21=4.266

 

б) сумма отрицательных десятичных логарифмов констант диссоциации по первой и второй ступеням

pk 22=5.518

 

Теперь необходимо создать пустой список (массив) для дальнейшего заполнения четырьмя величинами: C, MDTPK, [ L о] (это концентрации ДТПК или её натриевых солей со степенью замещения C, моль/л) и [ M о] (это концентрации ЩК, моль/л). Массив будет состоять из двух ячеек «[ ]», каждая из которых содержит по две величины («values»).

В первой ячейке, имеющей название «C_MDTPK_values», расположены кортежи, содержащие в себе C и MDTPK (выделение величин C и MDTPK в отдельную ячейку обусловлено тем, что величина C является той переменной, от которой зависит величина MDTPK).

Во второй ячейке, имеющей название «L0_M0_values», расположены кортежи, содержащие в себе [ L о] и [ M о].

Кортеж – это упорядоченный набор величин, имеющий фиксированную длину. В языке «Python» кортеж отличается от списка (массива) тем, что элементы кортежа нельзя изменять.

 

C_MDTPK_values=[ ]

L0_M0_values=[ ]

 

После того, как введены исходные данные справочного характера (константы диссоциации и молекулярные массы) и созданы пустые списки для дальнейшего заполнения величинами концентраций реагентов и степени замещения по натрию, нужно задать алгоритм, по которому определяется, какой вариант задачи мы будем решать – №1 или №2.

Для этого создаём переменную «prog_variant» (т.е. «программа расчёта для решения задачи по варианту №…») и присваиваем ей значение «1» (это номер варианта задачи).

 

prog_variant=1

 

Нижеследующий оператор требует выбрать конкретный вариант для решения задачи – или №1 (в этом случае отмывочный раствор содержит только комплексон, т.е. ДТПК или её натриевую соль с какой-либо степенью замещения по натрию), или №2 (для случая бинарного раствора
«комплексон + органическая кислота»). В этом операторе команда "raw_input(…)" позволяет ввести значение переменной в диалоговом окне компьютера; в скобках указывается текст, который выводится на экран монитора перед вводом.

 

prog_variant=int(raw_input('Komplekson=1, Komplekson+Organicheskayakislota=2, '))

 

Здесь команда «int» означает приведение в целочисленный формат всех величин, фигурирующих в операторе. Это необходимо, поскольку номер варианта задачи может быть только целым числом. При вводе в оператор любого нецелого числа будет зафиксирована ошибка, и выполнение программы прекратится.

Следующий оператор осуществляет проверку – допустимые ли номера вариантов будут выбираться для решения задачи (здесь знак «==» означает «сравнивание значений», в то время как знак «=» означает «присваивание значения»).

 

if prog_variant==1 or prog_variant==2:

 

Если задан допустимый номер варианта задачи (т.е. номер 1 или 2), то следует оператор «pass», который говорит о том, что выбор номера варианта выполнен корректно (т.е. из набора допустимых значений) и, следовательно, можно следовать дальше.

 

Pass

 

В противном случае, когда не выбран ни один из допустимых вариантов решения задачи (т.е. номер 1 или 2), следует команда "else:"

 

else:

и перечень дальнейших действий. В нашем случае это сообщение об ошибке («Error») и предложение выбрать номер варианта – 1 или 2.

Raise ValueError('Vyberite 1 ili 2!')

 

Для обоих вариантов решения задачи потребуются значения молекулярных масс натриевых солей ДТПК с различной степенью замещения C, которые нужно поместить в первую из двух ячеек ранее созданного списка (массива) величин, а именно: C_MDTPK_values.

Нижеследующий оператор даёт команду заполнять эту ячейку значениями степени замещения C от 1 до 5 с шагом 0,5 и вычисляемыми величинами молекулярной массы соответствующей натриевой соли ДТПК, равной «MDTPKC ·1,01 + C ·22,99». Здесь величина MDTPK = 393,35 была введена ранее как молекулярная масса натриевой соли ДТПК с замещением по натрию C = 0; 1,01 и 22,99 – это атомные массы водорода и натрия соответственно.

Команда "for i inrange(…)" задаёт повторение цикла вычислений необходимое число раз (это число равно разности второй и первой цифр, указанных в этом операторе внутри скобок). В нашем случае расчёт величины pH водного раствора ДТПК и её натриевых солей с различной степенью замещения по натрию C должен быть повторён i = 12– 1 = 11 раз – для значений C от 0 до 5 с шагом 0,5. Команда «append» означает добавление значений в список (массив), наименование которого значится перед этим словом.

for i in range(0, 11):

C=i*0.5

C_MDTPK_values.append((C,MDTPK_default-C*1.01+C*22.99))

 

Далее переходим к заполнению второй ячейки списка (массива), предназначенного для помещения в него величин концентраций реагентов, т.е. концентраций ДТПК или её натриевых солей с различной степенью замещения и щавелевой кислоты – [ L o] и [ M o] соответственно. Напомним, что в задаче по варианту №1 понадобятся 6 значений [ L o], а в задаче по варианту №2 – 5 значений [ L o] и 5 значений [ M o].

 

rep_count=5

 

Этот оператор означает, что по умолчанию количество задаваемых значений [ L o] и [ M o] равно 5. В ином случае это количество должно быть названо.

Поскольку в задаче по варианту №1 понадобится не 5, а 6 задаваемых значений [ L o] и [ M o], то это надо установить двумя нижеследующими операторами.

 

if prog_variant==1:

rep_count=6

 

Теперь можно переходить к заданию конкретных значений концентраций реагентов (отметим, что в языке программирования "Python" для вычисления «X в степени Y » применяют функцию "math.pow(X,Y)").

 

for i in range(0, rep_count):

if prog_variant==1:

L0_M0_values.append((math.pow(10, -7+i), 0))

else:

L0_M0_values.append((10-i*2.5, (i*2.5)/MSK))

Расчёт начинаем с объявления численного значения переменной (т.е. порядкового номера цикла), которая меняется в каждом очередном цикле вычислений.

 

count=0

Здесь переменная «count» служит для хранения количества повторений цикла расчёта.

При переходе к каждому новому циклу вычислений значения [ L o] и [ M o] берутся из соответствующих ячеек созданного списка (массива) величин.

 

for L0_raw, M0 in L0_M0_values:

for C, MDTPK in C_MDTPK_values:

 

Циклы вычислений проходят по каждому значению из этих списков. По умолчанию выполняются действия, необходимые для решения задачи по варианту №1. При совершении действий, необходимых для решения задачи по варианту №2, следует оговорить данное обстоятельство. Это означает, что концентрация ДТПК и её натриевых солей должна задаваться следующим образом.

 

if prog_variant==2:

L0=L0_raw/MDTPK

else:

L0=L0_raw

 

Эти 4 оператора требуют выполнить одно из двух действий: если решается задача по варианту №2, то «L0=L0_raw/MDTPK», а если не по варианту №2 (следовательно, по варианту №1), то «L0=L0_raw». Здесь слово «row», которое можно перевести как «сырое», означает начальное, т.е. исходное значение концентрации [ L o].

Отсюда видно, что для варианта №2 величина [ L o] задаётся в молях на литр, а для варианта №1 – в граммах на литр. Команда «else» здесь потребовала изменить номер варианта задачи со второго на первый.

Алгоритм (блок-схема) расчёта требует задания величин ионной силы и pH в первом приближении. Первое приближение по ионной силе выбираем с учётом формулы (19) для её расчёта, а в качестве первого приближения для величины pH принимаем середину интервала 0÷14, в котором она может изменяться.

 

m=0.5*(L0+M0)

ph=7

 

Поскольку эти две величины будут определяться методом последовательных приближений, нужно для каждой из них задать погрешность, с которой они будут вычислены.

 

e1=0.001

e2=0.001

 

Здесь e 1 и e 2 – погрешности вычисления ионной силы и величины pH раствора соответственно.

Нижеследующий оператор "while" задаёт выполнение тела цикла, пока не будет достигнуто заданное после слова "while" условие.

В соответствии с алгоритмом расчёта сначала методом последовательных приближений уточняется значение ионной силы раствора (с погрешностью e 1 = 0,001), а потом величина (с погрешностью e 2 = 0,001), поэтому операторы "while" располагаются в таком порядке:

 

while e2 >=0.001:

while e1 >=0.001:

 

Определяем вспомогательную величину A, необходимую для нахождения коэффициентов активности ионов.

 

A=math.sqrt(m)/(1+math.sqrt(m))-0.2*m

 

В этом операторе применёна команда "math…", которая в языке программирования "Python" используется для работы с числами. В данном случае для нахождения квадратного корня использована команда "math.sqrt(…)".

С помощью двух следующих операторов находим функции Q и Q 1.

 

Q=1+math.pow(10,pk11-ph-4.5*A)+math.pow(10,pk12-2*ph-8*A)+math.pow(10,pk13-3*ph-10.5*A)+math.pow(10,pk14-4*ph-12*A)+math.pow(10,pk15-5*ph-12.5*A)

Q1=5+4*math.pow(10,pk11-ph-4.5*A)+3*math.pow(10,pk12-2*ph-8*A)+2*math.pow(10,pk13-3*ph-10.5*A)+

math.pow(10,pk14-4*ph-12*A)

 

Находим относительные доли различных ионных форм ДТПК в водном растворе – L4-, HL3-, H2L2-, H3L-, H4Lо, H5L+ и H6L2+, соответственно.

 

a1=1/Q

a2=math.pow(10,pk11-ph-4.5*A)/Q

a3=math.pow(10,pk12-2*ph-8*A)/Q

a4=math.pow(10,pk13-3*ph-10.5*A)/Q

a5=math.pow(10,pk14-4*ph-12*A)/Q

a6=math.pow(10,pk15-5*ph-12.5*A)/Q

 

Находим функции B и B 1 для ЩК.

 

B=1+math.pow(10,pk21-ph-1.5*A)+math.pow(10,pk22-2*ph-2*A)

B1=2+math.pow(10,pk21-ph-1.5*A)

 

Находим относительные доли ионных форм ЩК в водном растворе – M2-, HM-, и H2Mо, соответственно.

 

v1=1/B

v2=math.pow(10,pk21-ph-1.5*A)/B

v3=math.pow(10,pk22-2*ph-2*A)/B

 

Вычисляем значение ионной силы раствора в новом приближении.

 

m1=0.5*L0*(25*a1+16*a2+9*a3+4*a4+1*a5)+0.5*M0*(4*v1+1*v2+0*v3)+

0.5*math.pow(10,-ph+0.5*A)+math.pow(10,ph-14+0.5*A)+0.5*C*L0

 

Сравниваем полученное значение m 1 с предыдущим приближением m. Для этого вычисляем разность этих двух величин по модулю.

 

e1=abs(m1-m)

 

В этом операторе функция "abs(…)" означает модуль числа, записанного в скобках.

В случае, если найденная величина e 1 окажется больше заданного значения 10-3, то принимаем m 1 за m

 

m=m1

 

и возвращаемся к началу цикла, повторяя его до тех пор, пока величина e 1 не перестанет превышать 10-3.

Определив значение ионной силы раствора m, а, значит, и величину A, переходим к нахождению водородного показателя среды рН из уравнения электронейтральности методом бисекции (т.е. методом половинного деления отрезка). Этот простейший численный метод применим в тех случаях, когда уравнение имеет единственный корень, причём в фиксированном интервале.

Действительно, уравнение электронейтральности раствора является трансцедентным и имеет единственное решение, поскольку для данного состава водного раствора в равновесном состоянии может установиться одно и только одно конкретное значение рН, причём в заранее известном диапазоне – от 0 до 14.

Задаем первые (начальные) значения левой ph 1 и правой ph 2 границ диапазона рН для решения уравнения электронейтральности.

 

ph1=0.0

ph2=14.0

 

Координату середины диапазона обозначим через ph 3.

Открываем цикл нахождения величины рН из уравнения электронейтральности, задавая условие окончания расчёта, а именно: при делении отрезка пополам длина последнего интервала рН по абсолютной величине не должна превышать заданную погрешность e 2.

 

while abs(ph2-ph1)>0.001:

 

Начинаем с того, что делим отрезок от 0 до 14 пополам.

 

ph3=(ph1+ph2)/2

 

Переносим в уравнении электронейтральности все слагаемые из правой части в левую и получившуюся в левой части всю сумму слагаемых вычисляем при трёх значениях аргумента – ph 1, ph 2 и ph 3. Получившиеся суммы обозначаем через f 1, f 2 и f 3 соответственно.

 

f1=L0*(5+4*math.pow(10,pk11-ph1-4.5*A)+

3*math.pow(10,pk12-2*ph1-8*A)+2*math.pow(10,pk13-3*ph1-10.5*A)+math.pow(10,pk14-4*ph1-12*A))/

(1+math.pow(10,pk11-ph1-4.5*A)+math.pow(10,pk12-2*ph1-8*A)+math.pow(10,pk13-3*ph1-10.5*A)+math.pow(10,pk14-4*ph1-12*A)+math.pow(10,pk15-5*ph1-12.5*A))-math.pow(10,

-ph1+0.5*A)+math.pow(10,ph1-14+0.5*A)-C*L0+M0*(2+math.pow(10,pk21-ph1-1.5*A))

/(1+math.pow(10,pk21-ph1-1.5*A)+math.pow(10,pk22-2*ph1-2*A))

f2=L0*(5+4*math.pow(10,pk11-ph2-4.5*A)+

3*math.pow(10,pk12-2*ph2-8*A)+2*math.pow(10,pk13-3*ph2-10.5*A)+math.pow(10,pk14-4*ph2-12*A))/

(1+math.pow(10,pk11-ph2-4.5*A)+math.pow(10,pk12-2*ph2-8*A)+math.pow(10,pk13-3*ph2-10.5*A)+math.pow(10,pk14-4*ph2-12*A)+math.pow(10,pk15-5*ph2-12.5*A))-math.pow(10,

-ph2+0.5*A)+math.pow(10,ph2-14+0.5*A)-C*L0+M0*(2+math.pow(10,pk21-ph2-1.5*A))/

(1+math.pow(10,pk21-ph2-1.5*A)+math.pow(10,pk22-2*ph2-2*A))

f3=L0*(5+4*math.pow(10,pk11-ph3-4.5*A)+

3*math.pow(10,pk12-2*ph3-8*A)+2*math.pow(10,pk13-3*ph3-10.5*A)+math.pow(10,pk14-4*ph3-12*A))

/(1+math.pow(10,pk11-ph3-4.5*A)+math.pow(10,pk12-2*ph3-8*A)+math.pow(10,pk13-3*ph3-10.5*A)+

math.pow(10,pk14-4*ph3-12*A)+math.pow(10,pk15-5*ph3-12.5*A))-math.pow(10,-ph3+0.5*A)+math.pow(10,ph3-14+0.5*A)-C*L0+M0*(2+math.pow(10,pk21-ph3-1.5*A))/

(1+math.pow(10,pk21-ph3-1.5*A)+math.pow(10,pk22-2*ph3-2*A))

 

Для принятия решения, какой из двух получившихся новых отрезков (от 0 до 7 или от 7 до 14) делить пополам в следующем цикле вычислений, нужно найти произведение функций f 1 и f 3.

Если это произведение меньше 0, то искомый корень уравнения находится в интервале между ph 1 и ph 3, а если больше 0, то в интервале между ph 3 и ph 2.

Решение принимается с помощью оператора "if (…):". Здесь в скобках записывается проверяемое условие.

 

if (f1*f3<0):

 

После этого оператора идёт последовательность команд, которые будут реализовываться, если условие выполнено. В нашем случае это оператор

 

ph2=ph3

 

Эта команда означает, что в следующем цикле вычислений середина отрезка от 0 до 14, то есть точка ph =7, станет правой границей нового диапазона поиска корня уравнений – это будет интервал ph между 0 и 7.

 

Оператором "elif" задаётся то следующее условие, которое должно быть проверено в случае, если не выполняется предыдущее условие (т.е. в случае, когда произведение функций f 1 и f 3 не окажется меньшим 0).

 

В нашем случае это следующее условие будет таким:

 

elif (f2*f3<0):

 

Если оно выполняется, то в следующем цикле вычислений середина отрезка от 0 до 14, то есть точка ph =7, станет левой границей нового диапазона поиска корня уравнений (это будет интервал ph между 7 и 14).

 

ph1=ph3

 

Если ни одно из проверенных условий – «f1*f3<0» или «f2*f3<0» – не выполняется, то далее следует команда "else:" и перечень дальнейших действий.

 

else:

print "Error"

 

В последнем операторе дана команда вывести на экран слово "Error" ("Ошибка"), поскольку одно из поставленных нами двух условий насчёт произведения функций ff 3 или ff 3 обязательно должно оказаться выполненным. Единственная возможность одновременного невыполнения двух таких условий – это равенство нулю какой-либо из перемножаемых функций, что для трансцедентного уравнения нереализуемо.

После каждого цикла вычислений по нахождению величины рН нужно проверить, не пора ли заканчивать расчёт. Для этого сравниваем полученное значение ph 3 с предыдущим приближением ph. С этой целью определяем разность данных величин по модулю.

 

e2=abs(ph-ph3)

 

В случае, если найденная величина e 2 окажется больше заданного значения 10-3, то принимаем ph 3 за ph

 

ph=ph3

 

и возвращаемся к началу цикла, повторяя его до тех пор, пока величина e 2 не перестанет превышать 10-3.

После этого с помощью команды "print" выводим на экран монитора (или на печать) необходимые нам результаты расчёта.

 

print "Results:"

 

Сначала на экран выводятся результаты расчёта для варианта №1, где использовались молярные концентрации реагентов.

if prog_variant==1:

print "Nomer tochki", count+1, ", ph=", ph, ", MO=", MO, ", LO=", LO, ", C=", C,

Затем на экран выводятся результаты для варианта №2. В этом случае нам нужны концентрации в граммах на литр, для чего молярные концентрации необходимо умножить на молекулярные массы соответствующих веществ.

else:

print "Nomer tochki", count+1, ", ph=", ph, ", MO=", MO*MSK, ", LO=", LO*MDTPK, "C=", C,

 

Следующий оператор задаёт последовательную нумерацию точек при выводе результатов вычислений на печать.

print "\n"

После этого идёт оператор, начинающий очередной цикл вычислений.

count=count+1

Последние два оператора фиксируют значения концентраций обоих реагентов и найденную величину ph водного раствора.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-10-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: