Soustavou nelineárních rovnic myslíme takovou soustavu rovnic, z
nichž je alespoň jedna nelineární. Vzhledem k tomu, že většina
nelineárních rovnic, resp. soustav nelineárních rovnic, není řešitelná
analyticky, musíme jejich kořeny hledat pomocí numerických metod, např.
metodou půlení intervalu nebo Newtonovou metodou. Jazyk Python má
nicméně ve svých knihovnách k dispozici numerické řešiče, které je možno
rychle implementovat. V této kapitole budeme potřebovat knihovnu
sympy
. Tu můžeme nainstalovat pomocí příkazu
pip install sympy
.
Jako příklad vezměme rovnici 1/x = exp(x), viz
Obr.1. Hledáme takovou hodnotu proměnné x
, jež danou
rovnici splňuje.
from sympy import Symbol, Eq, nsolve
= Symbol("x", real=True)
x = Eq(1 / x, exp(x))
rovnice = 0.5
pocatecni_nastrel = nsolve(rovnice, x, pocatecni_nastrel)
reseni print(reseni)
Při správném spuštění tohoto programu se na obrazovku vypíše řešení,
přibližně 0.5671
. Výsledek můžeme ještě dosadit zpět do
x
, pokud potřebujeme s vyčíslenou hodnotou dále
pracovat.
= reseni x
Pomocí funkce nsolve
lze rovněž řešit soustavu dvou i
více nelineárních rovnic. Pro příklad nalezněme průsečíky jednotkové
kružnice se středem v počátku souřadnic a jednoduchou sinusoidou,
zapsané rovnicemi rovnice1
a rovnice2
, viz
Obr.2.
from sympy import Symbol, Eq, nsolve
= Symbol("x", real=True)
x = Symbol("y", real=True)
y = [x, y]
nezname
= Eq(x ** 2 + y ** 2 - 1, 0)
rovnice1 = Eq(y - sin(x), 0)
rovnice2 = [rovnice1, rovnice2]
soustava_rovnic
= [1, 1]
pocatecni_nastrel
= nsolve(soustava_rovnic, nezname, pocatecni_nastrel)
reseni print(reseni)
Při správném spuštění tohoto programu se na obrazovku vypíše řešení,
přibližně 0.7391
a 0.6736
. Výsledek můžeme
ještě dosadit zpět do x
a y
, pokud potřebujeme
s vyčíslenými hodnotami dále pracovat.
= reseni x, y
Pokud zvolíme počáteční nástřel např. [-1, -1]
, program
nalezne druhé řešení odpovídající hodnotám -0.7391
a
-0.6736
.
V této sekci spočteme soustavu čtyř rovnic o čtyřech neznámých, vycházejících z reálného příkladu (Úloha 15-6b v Chemickém inženýrství I, kapitola Chemické reaktory).
Poznamenejme, že v této úloze se jedná o návrhový výpočet, v němž známe parametry na vstupu i na výstupu, a máme za úkol zjistit počet reaktorů v kaskádě, abychom získali požadovanou kumulativní konverzi vstupní suroviny.
Nejprve zde deklarujme mezivýsledky, které vycházejí z řešení 15-6a.
from sympy import Symbol, Eq, nsolve
= -2, 1, 1 # stech koef
nuA, nuB, nuC = 5.0 # m3/kmol/h
k_plus = 0.3125 # m3/kmol/h
k_minus = 6.2745 # m3
V0 = 1.50, 0.0, 0.0 # kmol/m3
cA0, cB0, cC0 = 0.433, 0.533, 0.533 # kmol/m3
cAN, cBN, cCN = 0.062745 # h
tau_dash = 0.711 zetaAN
Nyní proveďme řešení jedné iterace, tj. vypočteme kumulativní konverzi pro N-1 reaktor, kde N značí poslední reaktor v kaskádě. Takovéto řešení kaskády “odzadu” má výhodu v tom, že se vyhneme kvadratické rovnici (s neznámou kumulativní konverzí obecně k-1 reaktoru), jejíž výstupy bychom museli ošetřovat.
# Bilance slozky A v poslednim reaktoru (N) v kaskade
= cAN - nuA * (k_plus * cAN ** 2 - k_minus * cBN * cCN) * tau_dash
cAN_1
= Symbol("cAN_2", real=True)
cAN_2 = Symbol("cBN_1", real=True)
cBN_1 = Symbol("cCN_1", real=True)
cCN_1 = Symbol("zetaAN_1", real=True)
zetaAN_1
# Rovnice pro reaktor N-1
= Eq(cAN_2 - cAN_1 + \
rce1 * (k_plus * cAN_1 ** 2 - k_minus * cBN_1 * cCN_1) * tau_dash, 0)
nuA = Eq(cAN_1, cA0 * (1 - zetaAN_1))
rce2 = Eq(cBN_1, cB0 - nuB / nuA * cA0 * zetaAN_1)
rce3 = Eq(cCN_1, cC0 - nuC / nuA * cA0 * zetaAN_1)
rce4 = [rce1, rce2, rce3, rce4]
rovnice
= [cAN_2, cBN_1, cCN_1, zetaAN_1]
nezname
= [cAN_1, cBN, cCN, zetaAN]
pocatecni_nastrel = nsolve(rovnice, nezname, pocatecni_nastrel)
reseni = reseni
cAN_2, cBN_1, cCN_1, zetaAN_1 print(zetaAN_1)
Kumulativní konverze v N-1 reaktoru by měla vyjít
0.640
. Vzhledem k tomu, že je tato hodnota kladná, musíme v
příkladu analogicky řešit tyto rovnice v další iteraci.