desenvolvimento de software para problemas de...
Post on 31-Dec-2020
4 Views
Preview:
TRANSCRIPT
0
UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ
DEPARTAMENTO ACADÊMICO DE ENGENHARIAS
CURSO DE ENGENHARIA QUÍMICA
INGO LUIZ BOFF BRANDALISE
DESENVOLVIMENTO DE SOFTWARE PARA PROBLEMAS DE
DIMENSIONAMENTO DE REATORES CSTR
FRANCISCO BELTRÃO
2019
1
INGO LUIZ BOFF BRANDALISE
DESENVOLVIMENTO DE SOFTWARE PARA PROBLEMAS DE
DIMENSIONAMENTO DE REATORES CSTR
Trabalho de Conclusão de Curso em
Engenharia Química, apresentado à
disciplina de Trabalho de Conclusão de
Curso 2, do Departamento Acadêmico de
Engenharia Química da Universidade
Tecnológica Federal do Paraná como
requisito parcial para o título de bacharel
em engenharia química.
Orientador: Prof. Dr. Vilmar Steffen
FRANCISCO BELTRÃO
2019
2
FOLHA DE APROVAÇÃO
INGO LUIZ BOFF BRANDALISE
DESENVOLVIMENTO DE SOFTWARE PARA PROBLEMAS DE
DIMENSIONAMENTO DE REATORES CSTR
Trabalho de Conclusão de Curso
Obtenção do Título de Engenheiro
Químico
Universidade Tecnológica Federal do
Paraná
Campus Francisco Beltrão
Engenharia Química
Data da aprovação: Vinte e nove de novembro de 2019
___________________________________________
Orientador: Prof. Dr. Vilmar Steffen
___________________________________________
Membro da Banca: Prof(a). Dr(a). Ana Paula de Oliveira
Universidade Tecnológica Federal do Paraná
___________________________________________
Membro da Banca: Prof. Dr. Jeconias Rocha Guimarães
Universidade Tecnológica Federal do Paraná
A Folha de Aprovação assinada encontra-se na Coordenação do Curso.
3
AGRADECIMENTOS
Primeiramente quero agradecer a Deus, minha energia superiora que
sempre me iluminou e guiou meu caminho, auxiliando-me nas minhas decisões de
vida.
Aos meus pais, Cleiton e Daniele, que nunca mediram esforços para que
tudo em minha vida desse certo e fosse da melhor forma possível, que sempre me
incentivaram a nunca desistir e sempre trilhar o caminho certo. Se não fosse por
todo o apoio deles, eu não estaria escrevendo esse trabalho.
Ao meu irmão, Lucas, pelas brigas por eu não dar atenção a ele, pois estava
estudando e pesquisando sobre assuntos da faculdade, mas também por todos os
carinhos pela saudade de eu estar longe de casa e dele, principalmente.
Ao Prof. Dr. Vilmar Steffen, agradeço, não só pela orientação e por todo o
conhecimento repassado a mim, que foi de fundamental importância para o bom
desenvolvimento deste trabalho, mas pela compreensão de não ter conseguido
cumprir com o verdadeiro desafio desse trabalho, que, futuramente, quero
apresentar o real desafio cumprido.
Aos meus amigos que fiz durante esse curso (que foram muitos), pois eles
foram minha família durante esses anos:
A Joyce, pela mãezona sempre pronta a dar conselhos e me mostrar
caminhos que foram certeiros na minha vida.
A Vanessa, pela boa ouvinte e pela pessoa sempre pronta a nos fazer rir
com seus soluços espontâneos e seus bordões.
A Viviane, pelos bons rolês e por sempre estar pronta a tomar um
sorvetinho, além de sempre me colocar pra cima quando estava cabisbaixo.
A Bruno, por sempre estar nos ensinando ditados novos e sempre me
incentivando a nunca desistir dos meus projetos.
Aos Feras da EQ, pelos churrascos, beras e pelas partidas de baralho (o
jogo em específico que todos sabem que eu adoro), sempre proporcionando
momentos “inesquecíveis”.
A Gabriel Bortoleti, pela parceria que eu encontrei aqui em Francisco
Beltrão, pela boa comida, um bom gosto que partilhamos, e pelos bons momentos
compartilhados.
4
A José, por ter me auxiliado nos estudos de Python (mesmo sem conhecer)
durante madrugadas e horários livres, além dos momentos de estudos conjuntos.
A Gabriel Salvatti, um grande amigo de orquestra, por me ensinar formas de
descobrir os erros do meu algoritmo, e pelo compartilhamento de bons concertos
eruditos.
A Leonardo, por ter me ajudado a dar o pontapé inicial no processo de
escrita do código, pois sem ele, este trabalho não teria sido concluído.
Aos colegas da orquestra da UTFPR-FB, por sempre compreenderem
minhas faltas aos ensaios devido aos meus estudos e pelos bons momentos de
risadas e vexames próximo de pessoas que não nos conheciam.
A todas as pessoas que de alguma forma me auxiliaram no desenvolvimento
deste trabalho e que me ajudaram na minha formação profissional e pessoal durante
esses 5 anos de UTFPR, o meu muito obrigado.
5
RESUMO
Um grande problema se tem dentro da engenharia química quando o assunto é
simulação de processos químicos, que é a falta de softwares intuitivos de licença
gratuita para o público geral que lida com este ramo, como pesquisadores,
engenheiros industriais e estudantes. Muitos são os softwares para esse tipo de
trabalho, sendo um exemplo os simuladores modulares sequenciais, mas que
possuem licenças pagas que são muito caras. Com esse cenário, foi desenvolvido
um software direcionado à área de resolução de problemas de dimensionamento de
reatores do tipo CSTR. O objetivo desse software é a fácil utilização e o uso por um
público geral do ramo da engenharia química. Para o desenvolvimento desse
programa foi utilizado como base um método numérico que resolvesse sistemas de
equações não lineares de forma altamente convergente, sendo o método escolhido
o Método de Broyden. O modelo matemático obtido baseou-se em hipóteses
simplificadoras próprias de um reator CSTR, adicionando-se do caso de se
considerar reações elementares, mistura perfeita e reator ideal. E para o
desenvolvimento do programa foi escolhida a linguagem de programação Python
juntamente com sua biblioteca para elaboração da interface gráfica, Kivy. Estas
foram escolhidas por apresentarem fácil manipulação para escrita do código e fácil
entendimento por parte do usuário, caso este se interesse por alterar o código se
necessário. Com os exemplos de emprego do software apresentados, pode ser
percebido que foi possível obter um software para resolução de problemas de
dimensionamento de reatores do tipo CSTR e que possui grande aplicação na área
de análise e simulação de processos aplicados nessa área específica, o
dimensionamento de reatores CSTR.
Palavras-chave: Implementação. Software. Reatores.
6
ABSTRACT
The deficiency of intuitive softwares with free license for the general public is a big
problem inside of chemical engineering. Mainly for the researchers, industrial
engineers and students. Many are the softwares for this kind of work, for exemple,
the senquential modular simulators, but the licenses are so expensive. Considering
this, the development of a software directed to resolution sizing problems of CSTR
reactor is necessaring. The main goal of this software is an easier used and the used
for a general public of the chemical engineering area. For the development of this
programm it was used as base a numerical method that solved systems of nonlinear
equations of convergent way, using the Broyden Method. The math model was
based in simplifying hypotheses of a CSTR reactor, add the case of a elementar
reactions, perfect mix and ideal reactor. And to develops the programm it was
chosen the Python programming language together with your library for graphic
interface development, Kivy. These were used as result of an easier manipulation for
code script, simplifying the understanding for the user, if it interests for change the
code, if necessary. With the shown examples, it perceives that, it was possible to get
a software to resolution of sizing problems of CSTR reactors and that has big
application in this specific area, the CSTR reactors sizing.
Key words: Implementation. Software. Reactors.
7
SUMÁRIO
1 INTRODUÇÃO 8
2 OBJETIVOS 11
2.1 OBJETIVO GERAL 11
2.2 OBJETIVOS ESPECÍFICOS 11
3 FUNDAMENTAÇÃO TEÓRICA 12
3.1 INTRODUÇÃO AO BALANÇO DE MASSA E AO CÁLCULO DE REATORES 12
3.1.1 Cálculo de Reatores 13
3.2 SISTEMAS DE EQUAÇÕES NÃO LINEARES 18
3.2.1 Método de Newton-Raphson 21
3.2.2 Método de Broyden 24
3.3 LINGUAGEM DE PROGRAMAÇÃO PYTHON 25
4 PROCEDIMENTOS METODOLÓGICOS 27
5 RESULTADOS E DISCUSSÕES 31
5.1 EXEMPLO 1 31
5.2 EXEMPLO 2 37
6 CONCLUSÃO 41
REFERÊNCIAS 42
APÊNDICE A – CÓDIGO PYTHON 44
APÊNDICE B – CÓDIGO KIVY 73
8
1 INTRODUÇÃO
A simulação de processos químicos é uma grande área que possui muitas
aplicações no âmbito industrial. Esta área é muito difundida entre pesquisadores e
estudantes devido sua importância, principalmente no projeto de plantas industriais,
otimização e controle de processos. Devido o vasto conhecimento necessário para a
realização de simulações, muito se tem feito para facilitar os usuários deste ramo.
Como os problemas de engenharia química são, considerando problemas
reais, altamente não lineares, necessita-se de ferramentas que auxiliem na
resolução de problemas e/ou na tomada de decisões. Alguns exemplos podem ser
encontrados no comportamento de concentrações de componentes em reações,
processos de transferência de massa, no comportamento da queda de pressão por
escoamento em tubulações, entre outros. Essas propriedades dos processos são
variáveis dependentes, geralmente representadas por modelos matemáticos
(fenomenológicos ou empíricos), relacionadas como variáveis independentes do
processo, como a dimensão dos equipamentos. Normalmente, as equações que
descrevem o perfil dessas variáveis de processo não têm comportamento linear,
mas sim comportamentos exponenciais, logarítmicos, ou às vezes muito complexos
de se classificar. Como esses comportamentos não lineares são representados por
equações matemáticas muito complexas, cálculos manuais tornam-se trabalhosos e
impraticáveis. Contudo, com o avanço da ciência e da tecnologia, foram criadas
linguagens de programação de alto nível e softwares que auxiliassem nesses
cálculos. Esses softwares se baseiam em métodos e técnicas criadas e difundidas,
por demonstrarem grande proximidade com a realidade, para resolução de sistemas
de equações não lineares.
No entanto, normalmente os softwares mais eficientes possuem licença
paga, a preços pouco acessíveis. E, considerando a realidade do perfil das
empresas brasileiras, segundo Oliveira (2018), 70% da nossa indústria é formada
por micro e pequenas empresas, ficando estas impossibilitadas de adquirir softwares
muito caros devido ao orçamento limitado. De acordo com Duarte, Orellana e
Campos (2011), os recursos computacionais se tornam indispensáveis à atuação do
engenheiro químico, funcionando como uma ferramenta que lhe assegura maior
confiabilidade em relação à obtenção dos dados e ao seu tratamento. Por isso, na
maioria dessas empresas, os profissionais de engenharia química utilizam softwares
9
livres, desenvolvem softwares utilizando muitas dessas linguagens de programação
de alto nível, ou ainda, buscam auxílio de universidades para elaboração e
implantação de softwares por estudantes e pesquisadores. “Um software mais
simples, ou mais barato, desde que adaptado às necessidades e bem utilizado, pode
ser tão efetivo quanto as soluções mais caras e complexas” (VIEIRA, 2018).
Isso tudo mostra a importância de se ter um software à disposição para
agilidade na tomada de decisões, pois eles não auxiliam apenas na obtenção rápida
de resultados, mas sim nos possíveis cenários que podem vir a acontecer.
Uma das áreas da engenharia química, que há vários modelos não lineares,
é a engenharia das reações químicas, ou cinética de reatores. Os profissionais desta
área estudam os modelos matemáticos que descrevem a cinética química de
geração e/ou consumo de espécies químicas que ocorre dentro de reatores e os
possíveis mecanismos de reação que ocorrem, dependendo das condições do
processo e do tipo de reator utilizado. São três os principais tipos de reatores que
existem: reator batelada, no qual não há fluxo mássico/molar durante o processo, há
apenas o depósito do material reacional dentro do reator antes do processo; reator
CSTR (Continuous Stirred-Tank Reactor), ou Reator Tanque Agitado Contínuo, um
reator de escoamento contínuo (fluxo mássico de entrada de reagentes e saída de
produtos) no qual normalmente são conduzidas reações em fase líquida; e reator
tubular, de fluxo contínuo, em que considera-se, normalmente, não haver variação
das concentrações em relação ao raio do tubo, chamado de PFR (Plug Flow
Reactor), ou Reator de Fluxo Pistonado, utilizado para operar reações em fase
gasosa, em sua maioria.
Especificando a engenharia das reações químicas, os softwares mais
atrativos para essa área são aqueles de fácil compreensão para uso, pois, por se
tratar de uma área que possui cálculos de difícil manuseio matemático, o software
deve ser claro nos seus parâmetros e forma de utilização. Porém, muitos não são
assim. Estes possuem características e funções de grande abrangência, mas são de
difícil utilização, sendo necessário muito tempo de dedicação para aquisição de
conhecimento a respeito do seu funcionamento. Sendo assim, softwares intuitivos
estão em falta no mercado, sendo um benefício, a todos que atuam com engenharia
química, ter acesso a esse tipo de ferramenta.
O desenvolvimento de um software intuitivo, com interface gráfica de fácil
compreensão, que possa ser utilizado no mundo acadêmico, tanto por professores e
10
pesquisadores quanto por alunos e estudantes é de extrema importância, auxílio e
praticidade. Algo desse gênero pode vir como uma ferramenta de análise,
divulgação científica e também no processo de ensino. Dessa forma, este trabalho
buscou ser o mais compreensível e prático possível para que fosse atrativo ao uso.
Além disso, acompanhando a inovação que está acontecendo, em um
contexto global e atual, desenvolver um software que possa ser aplicado
profissionalmente, ou mesmo como uma escala piloto, é acompanhar os avanços da
Indústria 4.0. De acordo com Mongelli (2019), essa “Quarta Revolução Industrial”
tem por objetivo transformar a prática do processo de produção com as principais
inovações tecnológicas. Isso está ocorrendo de forma muito rápida, mas ao mesmo
tempo complexa, pois os pilares da Indústria 4.0 são a virtualização, que é a entrada
da tecnologia digital nas indústrias; a conectividade, fazendo os sistemas físico e
digital interagirem por meio da IoT (Internet of Things); a tomada de decisões,
utilizando Inteligência Artificial; e a modularidade, pois apesar das máquinas estarem
conectadas entre si por um sistema elas trabalham de forma independente para
melhor otimização dos processos.
Neste contexto, este trabalho visa a implementação computacional de um
modelo matemático para resolução de problemas de dimensionamento de reatores
do tipo CSTR para um número limitado de cinco componentes envolvidos em uma
reação química (incluindo inertes), no qual o usuário poderá selecionar qualquer
conjunto de incógnitas (especificando os parâmetros restantes), respeitando os
graus de liberdade do problema, da mesma forma como é abordado em simuladores
modulares sequenciais.
11
2 OBJETIVOS
Para o desenvolvimento desse projeto de pesquisa, foi feito uma abordagem
computacional com base em linguagem Python para resolução de problemas de
dimensionamento de reatores do tipo CSTR.
2.1 OBJETIVO GERAL
Desenvolver um software do ramo da engenharia de reações químicas para
a análise e resolução de problemas de dimensionamento de reatores do tipo CSTR.
2.2 OBJETIVOS ESPECÍFICOS
Resolver problemas de dimensionamento de reatores do tipo CSTR;
Ser intuitivo;
Poder ser usado no âmbito acadêmico, para divulgação científica, e
no âmbito profissional;
Agilizar o cálculo da cinética de reatores do tipo CSTR quando muito
complexos;
Fornecer praticidade na análise de problemas de cinética de reatores
sob a perspectiva de diferentes conjuntos de incógnitas;
Elaborar um algoritmo com base em linguagem de programação
Python que resolva os problemas propostos;
Elaborar uma interface gráfica para o software para que seja prático
para o usuário utilizá-lo.
12
3 FUNDAMENTAÇÃO TEÓRICA
3.1 INTRODUÇÃO AO BALANÇO DE MASSA E AO CÁLCULO DE REATORES
Um dos primeiros conceitos básicos que um engenheiro químico precisa ter
bem definido em sua base teórica acerca da engenharia química é a relação de um
processo químico com um balanço de massa. O balanço de massa nada mais é que
a aplicação de um princípio que foi enunciado no século XVIII. De acordo com
Russel (1994), em 1774, Antoine Laurent de Lavoisier enunciou a lei de conservação
da massa (ou matéria), “em um recipiente fechado, a soma das massas dos
produtos é igual a soma das massas dos reagentes”, ou, “na natureza nada se
perde, nada se cria, tudo se transforma”, pois durante uma reação química não
ocorre nem ganho nem perda de massa, apenas transformação.
Baseando-se nesse princípio, é possível escrever uma equação que
descreve um balanço de massa geral, aplicado a qualquer processo entre os
instantes de tempo 𝑡1 e 𝑡2, conforme descrito na equação (1).
𝐴𝑐ú𝑚𝑢𝑙𝑜𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
=𝐸𝑛𝑡𝑟𝑎𝑑𝑎𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
−𝑆𝑎í𝑑𝑎
𝑑𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
+𝐺𝑒𝑟𝑎çã𝑜𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
−𝐶𝑜𝑛𝑠𝑢𝑚𝑜𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
(1)
Segundo Himmelblau (2014), para entender o que descreve a equação (1) é
necessário que sejam definidos alguns termos:
Sistema: porção arbitrária onde está ocorrendo o processo a ser
analisado. Pode ser chamado também de volume de controle;
Estado estacionário ou processo contínuo: processo no qual nenhuma
das variáveis de processo varia em relação ao tempo;
Estado transiente: processo pelo qual há variáveis de processo que
variam em relação ao tempo. Um caso específico de um processo em
estado transiente é um processo em batelada, no qual é realizado
com uma quantidade fixa de massa, sem ocorrer entradas e saídas
do sistema;
Processo em semibatelada: processo semiaberto, ou seja, ocorre
entrada de massa no sistema, mas não ocorre saída.
13
De acordo com Junior e Cruz (2011), pode-se escrever dois tipos de
balanço: os diferenciais e os integrais. Os balanços diferenciais são usados quando
se necessita determinar o valor de uma variável em determinado instante de tempo,
pois uma equação diferencial considera variações infinitesimais da variável
independente (podendo ser o tempo em alguns casos, como pode ser também o
comprimento de um tubo). Já os balanços integrais têm suas aplicações quando se
quer saber a variação de uma determinada variável (concentração, por exemplo)
entre dois instantes de tempo diferentes, como se fosse uma variável de estado.
A partir desses termos e da definição de balanço de massa é possível
aplicar esses conceitos ao cálculo de reatores (ou cinética de reatores).
3.1.1 Cálculo de Reatores
O cálculo de reatores é um ramo da engenharia química. Profissionais que
trabalham neste ramo estudam a cinética das reações químicas a nível industrial a
partir da velocidade de reação química (𝑟). De acordo com Fogler (2014), esse
termo, 𝑟, representa a velocidade de reação química, sendo função das
concentrações das espécies presentes na reação (somente reagentes ou reagentes
e produtos), da temperatura e pressão do meio reacional, da presença e do tipo de
um catalisador e é independente do tipo de reator a qual a reação é posta para
operar.
Segundo Levenspiel (2000), algumas reações ocorrem muito rapidamente,
enquanto outras ocorrem de forma extremamente lenta, tudo dependendo da taxa
de reação. Em função disso, por existirem diferentes tipos de reatores em questão
de cor, tamanho e forma, cada processo deve ser tratado de forma diferente,
desenvolvendo uma equação de projeto para cada caso.
De acordo com Roberts (2010), com base em anos de estudos
experimentais e teóricos da cinética de muitas reações químicas, algumas
generalizações acerca da forma das equações de velocidade de reação se
consolidaram.
1. Em reações elementares (essencialmente irreversíveis), a taxa de
desaparecimento do reagente A pode ser representada pela equação
(2).
14
−𝑟𝐴 = 𝑘(𝑇)𝐹(𝐶𝐴, 𝐶𝐵, 𝐶𝐶 , … ) (2)
As influências das variáveis temperatura e concentração frequentemente são
separadas, ou seja, 𝑘(𝑇) representa a constante cinética que depende apenas da
temperatura e 𝐹(𝑡𝑜𝑑𝑎 𝐶𝑖), uma função que depende apenas das concentrações das
várias espécies presentes na reação.
2. A constante da taxa pode ser escrita na forma representada pela
equação (3).
𝑘(𝑇) = 𝐴 exp (−𝐸
𝑅𝑇) (3)
Onde R é a constante dos gases, T a temperatura, A um fator pré-
exponencial ou fator de frequência e E é a energia de ativação da reação. A
equação (3) é chamada de Equação de Arrhenius.
3. O termo 𝐹(𝐶𝐴, 𝐶𝐵, 𝐶𝐶 , … ) diminui à medida que as concentrações dos
reagentes diminuem, diminuindo juntamente a velocidade de reação.
4. O termo 𝐹(𝐶𝐴, 𝐶𝐵, 𝐶𝐶 , … ) pode ser escrito na forma apresentada pela
equação (4).
𝐹(𝐶𝐴, 𝐶𝐵, 𝐶𝐶 , … ) =∏𝐶𝑖𝛼𝑖
𝑖
(4)
A equação (4) representa o produto de todas as concentrações que
influenciam na velocidade de reação, sendo o termo 𝛼𝑖 chamado de ordem de
reação em relação ao componente i. Esta possui valor que variam, normalmente, de
0 a 2, podendo possuir valores fracionários.
5. Se uma reação é reversível, sua equação da velocidade de reação é
escrita como sendo a diferença entre as velocidades direta e inversa.
Nestes casos, em determinado momento a equação atinge o
equilíbrio químico, no qual a velocidade direta é igual a velocidade
inversa. Assim a equação da velocidade deve considerar a constante
de equilíbrio e é escrita no formato da equação (5).
15
−𝑟𝐴 = 𝑘(𝑇)( ∏ 𝐶𝑖𝛼𝑖
𝑅𝑒𝑎𝑔𝑒𝑛𝑡𝑒𝑠
𝑖
−∏ 𝐶𝑖
𝛼𝑖𝑃𝑟𝑜𝑑𝑢𝑡𝑜𝑠𝑖
𝐾𝑐) (5)
Sendo Kc a constante de equilíbrio do sistema.
Porém, deve-se lembrar que a constante de equilíbrio é uma variável
dependente da temperatura conforme a equação de Van’t Hoff, descrita na equação
(6).
𝑑(ln (𝐾))
𝑑𝑇=∆𝐻𝑟𝑥
𝑜
𝑅𝑇2 (6)
Segundo Fogler (2014), a lei de velocidade de reação é uma equação
algébrica, que pode ser tanto linear quanto não linear, ou seja, para uma reação
química do tipo descrito na equação (7):
𝐴 → 𝑝𝑟𝑜𝑑𝑢𝑡𝑜𝑠
(7)
A lei de velocidade pode ser conforme exemplificado na equação (8).
𝑟 = 𝑘𝐶𝐴 (8)
Ou conforme exemplificado na equação (9).
𝑟 =𝑘1𝐶𝐴
1 + 𝑘2𝐶𝐴 (9)
Onde:
𝑟: Velocidade de reação;
𝑘, 𝑘1 e 𝑘2: Constantes de velocidade específicas;
𝐶𝐴: Concentração do composto A.
Para que se possa verificar o quanto a velocidade de reação influencia no
processo é necessário colocá-la em um balanço material, contudo, o balanço que
16
está presente o termo da velocidade de reação é um balanço molar, pois a relação
de geração/consumo reacional é dada em base molar.
𝐴𝑐ú𝑚𝑢𝑙𝑜𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
=𝐸𝑛𝑡𝑟𝑎𝑑𝑎𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
−𝑆𝑎í𝑑𝑎
𝑑𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
±𝐺𝑒𝑟𝑎çã𝑜/𝐶𝑜𝑛𝑠𝑢𝑚𝑜
𝑛𝑜 𝑠𝑖𝑠𝑡𝑒𝑚𝑎𝑑𝑒 𝑡1 𝑎 𝑡2
(10)
Esse mesmo balanço representado pela equação (10) pode ser escrito com
base em vazões molares por componente e o acúmulo sendo representado por uma
taxa, que, quando tomado que o intervalo de tempo considerado tende a zero, essa
taxa se torna uma derivada, ou seja, é escrito um balanço diferencial, como na
equação (11).
𝑑𝑁𝑗
𝑑𝑡= 𝐹𝑗0 − 𝐹𝑗 + 𝐺𝑗
(11)
No termo de geração é preciso considerar que a reação está ocorrendo em
todo o sistema. A equação (12) representa o termo de geração.
𝐺𝑗 = ∫ 𝑟𝑗𝑑𝑉𝑉
0
(12)
Sendo 𝑉 o volume de controle, nem sempre temos a mesma quantidade de
reagente em todos os pontos do volume de controle, portanto não temos sempre o
mesmo grau de reação em todos os pontos.
Assim, pode-se escrever a equação (13) que é uma equação geral para as
reações químicas.
𝑑𝑁𝑗
𝑑𝑡= 𝐹𝑗0 − 𝐹𝑗 +∫ 𝑟𝑗𝑑𝑉
𝑉
0
(13)
A partir da equação (13) podem ser escritas as equações de projeto de
todos os tipos de reatores existentes. E para o presente trabalho, o reator utilizado
17
será o reator do tipo CSTR (reator tanque agitado contínuo) que é um reator
contínuo.
“Normalmente é operado em regime estacionário, e assume-se como tendo
uma mistura perfeita; isto é, os valores dessas variáveis não mudam de um ponto
para outro no interior do reator”. (FOGLER, 2014)
Como o reator CSTR, de interesse ser contínuo, o termo de acúmulo é
anulado, juntamente com a integral da velocidade de reação por ser considerada
uma mistura perfeita. Assim, a equação (13) se resume a:
0 = 𝐹𝑗0 − 𝐹𝑗 + 𝑟𝑗𝑉 (14)
Isolando a variável 𝑉, a equação (14) se resume na equação de projeto de
um CSTR (equação (15)).
𝑉 =𝐹𝑗0 − 𝐹𝑗
−𝑟𝑗 (15)
Considerando variáveis que são mais fáceis de serem medidas como vazão
volumétrica e concentração, a equação (15) pode ser escrita como apresentado na
equação (16).
𝑉 =𝑣0𝐶𝑗0 − 𝑣𝐶𝑗
−𝑟𝑗 (16)
Sendo: 𝑣0 e 𝑣, vazões volumétricas de entrada e saída, respectivamente e
𝐶𝑗0 e 𝐶𝑗, concentrações das correntes de entrada e saída, respectivamente.
Como a equação (16) pode ser escrita para cada componente participante
da reação, e os termos de volume, vazão volumétrica e velocidade de reação geral
são os mesmos para o processo em si, é possível agrupar as equações escritas de
cada componente em um sistema de equações. Mas como um sistema de equações
normalmente possui suas equações igualadas a um vetor nulo, a equação (16)
precisaria ser reescrita conforme representado na equação (14), considerando o
apresentado na equação (17):
18
𝑟𝑗 = 𝜈𝑗𝑟 (17)
Sendo que 𝜈𝑗 representa o coeficiente estequiométrico da componente 𝑗 na
reação e que as vazões se mantem constantes, a equação (18) se apresenta como
resumo da explicação.
𝑣0 (𝐶𝑗0 − 𝐶𝑗) + 𝜈𝑗𝑟𝑉 = 0 (18)
3.2 SISTEMAS DE EQUAÇÕES NÃO LINEARES
Equações não lineares se caracterizam pela presença de termos não
lineares ao longo da equação, isto é, são equações que não podem ser escritas no
formato 𝑎𝑥 + 𝑏𝑦 = 𝑐, sendo “a, b e c” constantes reais. “Porém 𝑎𝑥2 + 𝑏𝑦 = 𝑐 ou 𝑎𝑥 +
𝑏 ∗ 𝑒𝑥𝑝(𝑦) = 𝑐 são equações não-lineares”. (PINTO, 2001)
Segundo Pinto (2001), normalmente, esse tipo de equação não possui
solução analítica, sendo necessário utilizar algum método numérico para encontrar
sua solução aproximada. A solução encontrada por métodos numéricos é dita
aproximada pois por menor que seja a precisão do método, sempre haverá um erro
em relação à solução exata.
Frequentemente, os problemas reais não envolvem apenas uma única
equação não-linear, mas sim um sistema de equações não-lineares.
Burden (2015) diz que, como sistemas de equações não-lineares são, de
certa forma, complexos de se resolver, normalmente, evita-se resolvê-los
analiticamente e opta-se por utilizar métodos de aproximação dos valores exatos,
dentre os quais há alguns que são adaptados a partir de séries de Taylor truncadas
no segundo termo.
Por definição, dada uma função não linear 𝐹 = (𝑓1, 𝑓2, … , 𝑓𝑛)𝑇, sua solução
será encontrada fazendo-se o apresentado na equação (19).
𝐹(𝑋) = 0 (19)
Sendo X um vetor coluna com n variáveis independentes (equação (20)):
19
𝑋 = (𝑥1, 𝑥2, … , 𝑥𝑛)𝑇 (20)
No formato de sistema, o conjunto de equações é representado pela
equação (21).
{
𝑓1(𝑥1, 𝑥2, … , 𝑥𝑛) = 0
𝑓2(𝑥1, 𝑥2, … , 𝑥𝑛) = 0⋮
𝑓𝑛(𝑥1, 𝑥2, … , 𝑥𝑛) = 0
(21)
Ou seja, resume-se à equação (22).
𝐹(𝑋) = (
𝑓1(𝑋)𝑓2(𝑋)⋮
𝑓𝑛(𝑋)
) = (
𝑓1(𝑥1, 𝑥2, … , 𝑥𝑛)𝑓2(𝑥1, 𝑥2, … , 𝑥𝑛)
⋮𝑓𝑛(𝑥1, 𝑥2, … , 𝑥𝑛)
) = 0 (22)
De acordo com Pinto (2001), os métodos numéricos de resolução de
sistemas de equações não-lineares podem ser classificados em dois grupos:
Métodos Diretos: dos quais não fazem uso de cálculo de derivadas de
F(X) nem de aproximações destas derivadas;
Métodos Indiretos: dos quais fazem uso do cálculo de derivadas de
F(X) ou de aproximações destas derivadas de modo a acelerar a
convergência do método numérico.
Como a função a ser resolvida pode ser escrita em um formato matricial, as
derivadas utilizadas pelos métodos indiretos também comporão uma matriz, a matriz
Jacobiana, representada pela equação (23).
𝐽(𝑋) =
(
𝜕𝑓1(𝑋)
𝜕𝑥1
𝜕𝑓1(𝑋)
𝜕𝑥2𝜕𝑓2(𝑋)
𝜕𝑥1
𝜕𝑓2(𝑋)
𝜕𝑥2
…𝜕𝑓1(𝑋)
𝜕𝑥𝑛
…𝜕𝑓2(𝑋)
𝜕𝑥𝑛⋮ ⋮
𝜕𝑓𝑛(𝑋)
𝜕𝑥1
𝜕𝑓𝑛(𝑋)
𝜕𝑥2
⋱ ⋮
…𝜕𝑓𝑛(𝑋)
𝜕𝑥𝑛 )
(23)
20
A matriz Jacobiana representa um conjunto de vetores gradientes denotados
por ∇𝑓𝑖(𝑋), 𝑖 = 1,2, … , 𝑛.
Dessa forma, a matriz Jacobiana também pode ser escrita baseada nos
vetores gradientes da função 𝐹(𝑋).
𝐽(𝑋) = ∇𝑓𝑖(𝑋) = (
∇𝑓1(𝑋)∇𝑓2(𝑋)⋮
∇𝑓𝑛(𝑋)
) =
(
𝜕𝑓1(𝑋)
𝜕𝑥1
𝜕𝑓1(𝑋)
𝜕𝑥2𝜕𝑓2(𝑋)
𝜕𝑥1
𝜕𝑓2(𝑋)
𝜕𝑥2
…𝜕𝑓1(𝑋)
𝜕𝑥𝑛
…𝜕𝑓2(𝑋)
𝜕𝑥𝑛⋮ ⋮
𝜕𝑓𝑛(𝑋)
𝜕𝑥1
𝜕𝑓𝑛(𝑋)
𝜕𝑥2
⋱ ⋮
…𝜕𝑓𝑛(𝑋)
𝜕𝑥𝑛 )
(24)
pois:
∇𝑓𝑖(𝑋) = (𝜕𝑓𝑖(𝑋)
𝜕𝑥1
𝜕𝑓𝑖(𝑋)
𝜕𝑥2…
𝜕𝑓𝑖(𝑋)
𝜕𝑥𝑛) (25)
Como é visto desde a equação (21) que as matrizes das funções e
Jacobiana, de forma geral, abordam n incógnitas e n equações, métodos numéricos
são necessários para se calcular as derivadas parciais das n equações em relação
às n incógnitas. E, como na maioria dos problemas as funções não são simples, é
prático optar pelo uso de aproximações para essas derivadas. Um método muito
usual é o método das diferenças centradas, representado pela equação (26):
𝜕𝑓𝑗(𝑋)
𝜕𝑥𝑘≅𝑓𝑗(𝑥1, 𝑥2, … , 𝑥𝑘 + ℎ𝑘, … , 𝑥𝑛) − 𝑓𝑗(𝑥1, 𝑥2, … , 𝑥𝑘 − ℎ𝑘, … , 𝑥𝑛)
2ℎ𝑘 (26)
O termo ℎ𝑘 representa uma variação no valor da variável em que se está
avaliando a derivada parcial, ou seja, como se está derivando a função 𝑓𝑗 em relação
a variável 𝑥𝑘, esta será a variável que terá variação no seu valor. Quanto menor o
valor de ℎ𝑘 mais precisa será a derivada. Entretanto valores muito pequenos podem
causar erros na resolução devido à possíveis limitações do computador.
Um possível valor de ℎ𝑘 é o apresentado na equação (27).
ℎ𝑘 = 0,001𝑥𝑘 (27)
21
3.2.1 Método de Newton-Raphson
O método de Newton-Raphson é um dos métodos mais amplamente
estudados e conhecidos para se resolver sistemas de equações não-lineares. Ele se
assemelha muito ao método de Newton aplicado na resolução de equações não-
lineares com uma única variável.
O Método de Newton para resolução de equações não lineares de uma
variável é baseado na aproximação linear em torno de um ponto qualquer 𝑥𝑘,
considerando uma série de Taylor truncada no segundo termo (termo da derivada
primeira). Esse truncamento está representado na equação (28).
𝑓(𝑥) = 𝑓(𝑥𝑘) + 𝑓′(𝑥𝑘)(𝑥 − 𝑥𝑘) (28)
Isolando a variável 𝑥 na equação (28), fica-se com descrito na equação (29).
𝑥 = 𝑥𝑘 −𝑓(𝑥𝑘) − 𝑓(𝑥)
𝑓′(𝑥𝑘) (29)
Como estamos buscando uma raiz para a equação, isso pode ser
representado conforme a equação (30).
𝑓(𝑥) = 0 (30)
Desta forma, como é um processo iterativo, o valor encontrado para 𝑥 é a
“possível” raiz da equação. Assim, renomeando as variáveis da equação (29) e
substituindo a equação (30) na equação (29), tem-se a equação (31) utilizada para o
processo iterativo.
𝑥𝑘+1 = 𝑥𝑘 −𝑓(𝑥𝑘)
𝑓′(𝑥𝑘) (31)
22
Essa dedução foi feita de forma a facilitar o entendimento da equação geral
do Método de Newton-Raphson para sistemas de equações não-lineares que regula
o processo iterativo.
Como sistemas de equações normalmente são representados na forma de
vetores, para fazer a comparação entre o método de Newton-Raphson para uma
equação e para um sistema de equações, a variável 𝑥 é substituída por um vetor de
variáveis 𝑋 = (𝑥1, 𝑥2, … , 𝑥𝑛), a função 𝑓(𝑥) é substituída por um vetor de funções
𝐹(𝑋) = [𝑓1(𝑋), 𝑓2(𝑋),… , 𝑓𝑛(𝑋)] e a derivada primeira 𝑓′(𝑥) é substituída por uma
matriz de derivadas parciais de cada uma das funções em relação a cada uma das
variáveis, a matriz jacobiana, 𝐽(𝑋).
Escrevendo a equação geral do método e fazendo as substituições de
equação algébrica para equação vetorial obtem-se a equação (32).
𝑋𝑘+1 = 𝑋𝑘 −𝐹(𝑋𝑘)
𝐽(𝑋𝑘) (32)
Considerando que:
𝑋𝑘+1 − 𝑋𝑘 = ∆𝑋𝑘 (33)
E rearranjando a equação (32), resulta-se na equação (34).
𝐽(𝑋𝑘)∆𝑋𝑘 = −𝐹(𝑋𝑘) (34)
Segundo Santos (2016), a ampla utilização do método de Newton-Raphson
decorre de suas caraterísticas, entre elas a convergência local quadrática.
O processo iterativo desse método tem início com uma estimativa inicial 𝑋0 e
continua até uma determinada precisão ser atingida. Essa precisão é escolhida a
partir do nível de precisão que se necessita obter a solução, e pode ser avaliada
mediante cálculo das normas (representadas nas equações (35) e (36)), tanto da
variação ∆𝑋𝑘, quanto da função 𝐹(𝑋𝑘):
23
‖∆𝑋𝑘‖ = √∑∆𝑥𝑘𝑖2
𝑛
𝑖=1
< 𝜀1 (35)
‖𝐹(𝑋𝑘)‖ = √∑𝑓𝑖(𝑋𝑘)2𝑛
𝑖=1
< 𝜀2 (36)
O algoritmo do Método de Newton-Raphson funciona da seguinte maneira:
1. Entrada de dados iniciais:
a) 𝑘 = 0;
b) Estimativa inicial (ponto incial) 𝑋0;
c) Precisões 𝜀1 e 𝜀2;
d) Sistema de equações;
e) Equação que descreve o cálculo da Jacobiana.
2. Cálculo da solução inicial 𝐹(𝑋𝑘);
3. Cálculo da Jacobiana no ponto inicial 𝐽(𝑋𝑘);
4. Cálculo da mudança de valor da variável vetorial 𝑋 por meio da
Eq(16);
5. Cálculo da solução vetorial aproximada 𝑋𝑘+1 por meio da Eq(15);
6. Avaliar as precisões:
a) Se ‖∆𝑋𝑘‖ < 𝜀1 ou ‖𝐹(𝑋𝑘)‖ < 𝜀2, então 𝑋 = 𝑋𝑘+1 e seguir para o
passo 7;
b) Senão, fazer 𝑘 = 𝑘 + 1 e retornar ao passo 2.
7. Imprimir resultados
Uma etapa que exige grande tempo computacional é o cálculo da Jacobiana
a cada nova iteração, pois se a função for muito grande, são muitos os cálculos que
o computador precisa fazer. Dessa forma, um método, chamado de Método de
Newton Modificado, foi criado para que a Jacobiana utilizada fosse calculada apenas
24
uma vez, em torno do ponto inicial. A equação geral do método de Newton
Modificado está representada pela equação (37).
𝐽(𝑋0)∆𝑋𝑘 = −𝐹(𝑋𝑘) (37)
Dessa forma, uma solução será encontrada considerando as precisões
escolhidas, porém a convergência deixa de ser quadrática e passa a ser linear.
O Método de Newton Modificado está em uma classificação de métodos de
resolução de sistemas de equações não lineares que são modificados a partir do
Método de Newton-Raphson, ou seja, são métodos que possuem taxa de
convergência e precisão de resultados melhores.
Um método muito utilizado na resolução de sistemas de equações não
lineares que possui boa precisão e boa taxa de convergência, sem precisar se
preocupar com a estimativa inicial é o Método de Broyden.
3.2.2 Método de Broyden
Esse método possui um fator de relaxação adicionado na sua equação. Esse
fator de relaxação é multiplicado pela diferença entre a estimativa anterior e a
posterior para que o processo de convergência seja acelerado ou para que se
obtenha convergência em um processo de divergência. O segredo do Método de
Broyden é alterar o fator de relaxação a cada iteração. Apesar do esforço
computacional aumentar, a convergência também aumenta. Sendo que esse fator só
é diferente da unidade quando necessário para se evitar a divergência.
Considerando a equação (33), o Método de Broyden pode ser obtido da
seguinte maneira.
Rearranjando a equação (33), obtem-se a equação (38).
𝑋𝑘+1 = 𝑋𝑘 + ∆𝑋𝑘 (38)
.
O fator de relaxação é multiplicado pelo ∆𝑋𝑘. Desse forma, a equação (39) o
apresenta como sendo 𝑠𝑖𝑘.
25
𝑋𝑘+1 = 𝑋𝑘 + 𝑠𝑖𝑘∆𝑋𝑘 (39)
Para saber quando o fator possuirá valor diferente da unidade, é avaliada a
desigualdade entre as normas Euclidianas (equação (40)).
√∑𝑓𝑗2(𝑋𝑘 + 𝑠𝑖𝑘∆𝑋𝑘)
𝑛
𝑗=1
< √∑𝑓𝑗2(𝑋𝑘)
𝑛
𝑗=1
(40)
Caso essa desigualdade não seja verdadeira, o valor do fator 𝑠 deve ser
alterado conforme a equação (41).
𝑠2𝑘 =√1 + 6𝜂 − 1
3𝜂 (41)
Sendo 𝜂 a razão entre as normas Euclidianas representadas na equação
(40) ao quadrado.
𝜂 =∑ 𝑓𝑗
2(𝑋𝑘 + 𝑠𝑖𝑘∆𝑋𝑘)𝑛𝑗=1
∑ 𝑓𝑗2(𝑋𝑘)
𝑛𝑗=1
(42)
3.3 LINGUAGEM DE PROGRAMAÇÃO PYTHON
De acordo com Perkovic (2016), Python é uma linguagem de uso geral e que
possui uma biblioteca muito completa, permitindo criar códigos relativamente simples
e fáceis de se entender. Isso é vantajoso na escolha dessa linguagem de
programação, além dela ser livre.
“É uma linguagem de programação multi-paradigma, pois suporta orientação
de objeto, programação imperativa e, em menor escala, programação funcional”.
(VAZ, 2018)
26
Esta linguagem de programação permite a um iniciante escrever códigos
sem necessitar escrever os códigos do princípio, pois as bibliotecas auxiliam na
escrita do código e complementam informações de forma prática.
De acordo com Santana (2019), Python é a linguagem de programação mais
utilizada na atualidade, pelo menos no mundo do desenvolvimento de aplicações
para computador e para a web. Segundo o estudo, Python é usado tanto na
academia quanto nas indústrias e está crescendo sua popularidade nas escolas e
nos negócios.
27
4 PROCEDIMENTOS METODOLÓGICOS
O presente trabalho foi executado com base tecnológica. O mesmo tem uma
pesquisa de certa forma descritiva, pois um assunto já conhecido (que é a solução
de problemas de reatores CSTR) foi tratado de uma forma mais geral, evitando o
que é feito na abordagem do conteúdo apresentado na disciplina de “Cálculo de
Reatores”, em que, para cada caso é feita uma análise e, dependendo das
incógnitas tem-se uma metodologia de solução diferente.
Para os problemas de dimensionamento de equipamentos de processos
químicos, por se tratar de um modelo matemático, hipóteses simplificadoras devem
ser apontadas para simplificação do modelo. Na construção do programa, deve-se
ter em mente que, estas hipóteses devem ser enunciadas para que o usuário esteja
ciente de que tipo de problemas o software tratará.
Dessa forma, as hipóteses simplificadoras para se chegar no modelo
matemático da equação (18) foram:
Estado estacionário (por se tratar de um CSTR);
Volume constante;
Mistura perfeita;
Vazão volumétrica constante;
Reator ideal, ou seja, o tempo de permanência das moléculas dentro
do reator é o mesmo do tempo espacial, não gerando volume morto
ou caminhos preferenciais;
Reação química elementar;
Processo isotérmico.
Assim, com essas hipóteses foi possível realizar a construção do modelo
matemático que foi desenvolvido na seção 3.1.1, desde a equação (11) até a
equação (18), que representa o modelo obtido que foi usado para desenvolvimento
do software.
Para que seja possível a solução do sistema que é formado com as
equações de cada componente com base na equação (18) foi escolhido um método
numérico de solução: o método de Broyden, que foi apresentado na seção 3.2.2.
Para elaboração do software, a linguagem utilizada foi o Python. Dentre as
várias bibliotecas disponíveis para Python, para a implementação do modelo e do
28
método utilizado para resolução do sistema de equações não lineares, foi utilizada a
biblioteca numpy que permite que sejam feitos cálculos matriciais de fácil execução.
Simultaneamente ao numpy, foi usada outra biblioteca para desenvolvimento da
interface gráfica: o kivy. Esta biblioteca foi utilizada em outro arquivo, no qual está
descrita a forma de disposição das janelas da interface gráfica.
Em Python, foi implementado o sistema de equações que representa o
modelo matemático e o método numérico utilizado para resolver este sistema de
equações não lineares. O código do modelo matemático implementado e da
interface gráfica estão localizados nos Apêndices A e B, respectivamente.
O modelo matemático, composto por um balanço molar para cada
componente, é apresentado na equação (43).
𝑣0𝑉(𝐶𝑗0 − 𝐶𝑗) + 𝜈𝑗𝑟 = 0 (43)
Sendo que a lei de velocidade r, é representada pela equação (44).
𝑟 = 𝑘(∏𝐶𝑗|𝜈𝑗|−𝜈𝑗2
5
𝑗=1
−∏𝐶𝑗|𝜈𝑗|+𝜈𝑗2
𝐾𝑐
5
𝑗=1
) (44)
Esta forma de representação do modelo facilita a implementação para um
número variável de componentes.
Para execução do problema, o usuário precisa fornecer alguns parâmetros,
para que seja possível iniciar a etapa de solução. Para saber quais são os
parâmetros necessários, é preciso fazer uma análise dos graus de liberdade do
sistema.
Como tem-se uma equação de balanço molar para cada componente, o
número de equações do modelo é igual ao número de componentes. Por questões
de dificuldade de implementação do código foram considerados 5 componentes,
com 𝑗 = 1,2,3,4,5, ou seja, no total foram 5 equações. Quando o número de
componentes for menor, é preciso informar alguns parâmetros com valores nulos,
sendo que, a forma de fazer isto será apresentada na seção de resultados e
discussões, juntamente com a forma de utilização do software.
29
Contando o número de incógnitas do problema (5 concentrações de entrada,
5 concentrações de saída, volume reacional, vazão volumétrica, constante de
equilíbrio e constante de velocidade específica) tem-se um total de 14 incógnitas.
Considerando conhecidos os coeficientes estequiométricos, o grau de liberdade (𝐺𝐿)
do sistema pode ser calculado conforme a equação (42).
𝐺𝐿 = 𝑛𝑣𝑎𝑟 − 𝑛𝑒𝑞 (42)
Sendo: nvar = número de variáveis e neq = número de equações.
𝐺𝐿 = 14 − 5 (43)
𝐺𝐿 = 9 (44)
Portanto, para que o programa consiga calcular uma solução, é necessário
informar 9 variáveis ao programa. Sendo que é possível qualquer combinação
destas.
Quanto à interface gráfica do sistema, esta foi desenvolvida de forma a ter
uma sequência lógica e intuitiva ao usuário para que seja de fácil interpretação. Ou
seja, esta possui uma janela de abertura, uma janela com instruções, outra em que
devem ser informados os valores dos coeficientes estequiométricos e, por fim, outra
em que são informados os 9 valores conhecidos para que o programa calcule a
solução.
Essa sequência lógica foi transcrita em código no arquivo kivy para que o
programa abra uma janela referente a interface gráfica do software.
Após concluídas as escritas dos códigos em Python e em Kivy, foram
realizados testes para que se verificasse a validade do programa e fossem feitas as
devidas correções e/ou adaptações no código.
O software foi desenvolvido para que o usuário siga uma sequência lógica e
intuitiva de alimentação de dados. Essa sequência, que é a mesma que o programa
segue, está descrita na Figura 1.
30
Figura 1 – Fluxograma referente à sequência do algoritmo do software
Fonte: Autoria Própria (2019).
Para que o usuário consiga utilizar o software, é necessário que o mesmo
possua instalado em seu computador um interpretador Python, disponível no site
oficial do Python, além das bibliotecas utilizadas pelo programa, numpy e kivy, que
podem ser baixadas via Prompt de Comando. Com essas ferramentas qualquer
computador pode utilizar o software. É recomendada sua utilização em sistema
operacional Linux, porém não é obrigatório.
31
5 RESULTADOS E DISCUSSÕES
A elaboração do software não foi algo simples, pois muitos dos erros
ocorridos no decorrer da escrita do código eram erros de indentação.
Como o software foi desenvolvido como piloto (primeiro), tem muito para
melhorar ainda. Dessa forma, não possui formas de se escolher a solução inicial,
sendo que esta foi fixada no código. Da mesma forma isso acontece com a
tolerância do erro, com o tamanho do passo inicial para o processo iterativo e com o
número de iterações, que também foram fixados no código. Sendo assim, o software
possui fragilidades nesses campos em que o usuário não possui maneiras de alterar
para melhor aproveitamento do programa.
A utilização do software obtido será apresentada com a solução de dois
exemplos.
5.1 EXEMPLO 1
O primeiro exemplo consiste em:
Um reator CSTR com um volume de 2280 L, destinado a produção de um
produto B e um produto C a partir de um reagente A. Essa reação é reversível e
elementar, como mostrado na equação (45):
𝐴 ↔ 𝐵 + 𝐶 (45)
O processo opera a uma vazão volumétrica de 3 Ls-1, sendo que na entrada
tem-se o componente A puro a uma concentração de 0,06 molL-1. A constante
cinética da reação a 1000 K é de 0,072 s-1. A constante de equilíbrio da reação a
1000 K é de 0,1 molL-1. Neste exemplo deseja-se saber os valores das
concentrações de saída dos três componentes, cuja solução é:
CA = 0,018 molL-1
CB = 0,042 molL-1
CC = 0,042 molL-1
32
Ao utilizar o software, obtido como produto deste trabalho, o usuário
navegará por janelas bastante intuitivas, ou seja, que indicarão ao mesmo como
proceder. A janela de apresentação (primeira janela), apresentada na Figura 2,
indica para que tipo de problemas o software é indicado.
Figura 2 – Janela inicial do software
Fonte: Autoria própria (2019).
Ao clicar no botão “Iniciar”, será mostrada a segunda janela, onde será
instruído a como utilizar o software para que consiga utilizá-lo da melhor forma
possível. A segunda janela é apresentada na Figura 3.
33
Figura 3 – Janela de instruções do software
Fonte: Autoria própria (2019).
As instruções explicam que o software pode ser usado para processo com
até cinco componentes e ensina como utilizá-lo caso o processo considerado
possua menos de cinco componentes. Também instrui quantos parâmetros devem
ter seus valores especificados para que o software possa executar a rotina numérica
de solução, pois se for especificado um número diferente de parâmetros, não é
possível fazer o cálculo.
Como o software considera reações reversíveis, para casos em que a
reação é irreversível, indica-se a utilização de um valor bastante elevado para a
constante de equilíbrio Kc, pois nas equações de balanço material, a constante de
equilíbrio encontra-se no denominador de uma fração, consequentemente, um valor
elevado da constante de equilíbrio fará com que o cálculo da fração seja
praticamente nulo. O software sugere a utilização de do valor 109, que foi o valor que
apresentou interferência praticamente nula nos testes feitos com outros exemplos.
Ao clicar no botão “Próximo”, será mostrada a primeira janela de
alimentação de dados. Os primeiros dados a serem fornecidos serão os dados
referentes aos coeficientes estequiométricos da reação. Caso o processo
considerado possua menos de cinco componentes, deve-se atribuir valor nulo aos
coeficientes estequiométricos fornecidos dos componentes que devem ser
desconsiderados. Isto é equivalente à especificação de espécies inertes. O software
34
ainda traz um lembrete de que o coeficiente estequiométrico de reagentes deve ser
negativo e de inertes, zero. A terceira janela, onde devem ser especificados os
coeficientes estequiométricos, é apresentada na Figura 4.
Figura 4 – Janela de alimentação de dados referentes aos coeficientes estequiométricos da reação
Fonte: Autoria própria (2019).
Com os dados do primeiro exemplo, a janela 3 ficaria conforme ilustrado na
Figura 5.
35
Figura 5 – Janela com dados de coeficientes estequiométricos referentes ao exemplo 1
Fonte: Autoria própria (2019).
Ao clicar no botão “Próximo”, o usuário é direcionado à última janela do
software, ilustrada na Figura 6, no qual informará os dados referentes ao processo
em si. Nesta última janela, caso a reação considerada não possua os cinco
componentes, para que o programa consiga realizar o cálculo, devem ser inseridos
valores iguais a zero nos campos referentes às concentrações de entrada dos
componentes inexistentes.
36
Figura 6 – Janela final, onde serão calculadas as variáveis de interesse do usuário
Fonte: Autoria própria (2019).
Ao informar os dados do exemplo 1, a última janela ficaria conforme ilustrado
na Figura 7.
Figura 7 – Janela final com dados referentes ao exemplo 1
Fonte: Autoria própria (2019).
37
Ao clicar no botão “Calcular”, as funções presentes no código irão calcular a
solução e a mesma janela mostrará os resultados indicando as variáveis calculadas
na cor verde, conforme ilustrado na Figura 8.
Figura 8 – Janela final com os resultados referentes ao exemplo 1
Fonte: Autoria própria (2019).
Caso o usuário queira verificar novamente o resultado, o mesmo pode clicar
no ícone “Limpar” que fará com que as células voltem ao estado inicial, como na
Figura 6. Porém, deve-se lembrar que não é possível realizar o cálculo de outro
problema apenas clicando em “Limpar”, pois o programa ainda está com os dados
dos coeficientes estequiométricos armazenados conforme informados na janela 3
(Figura 5). Para fazer o cálculo de outro problema, o usuário deverá fechar o
software e abri-lo novamente para que as variáveis do código recebam novas
informações.
5.2 EXEMPLO 2
No segundo exemplo tem-se a seguinte reação, exemplificada pela reação
(46), do componente A se transformando no produto B:
38
𝐴 → 𝐵 (46)
Sendo esta reação irreversível e elementar, tem-se como incógnita o volume
do reator CSTR necessário considerando uma vazão volumétrica de 10 Ls-1 com
reagente A sendo alimentado a uma concentração de 3 molL-1 juntamente com um
componente inerte a uma concentração de 0,1 molL-1. A constante cinética é de
0,056 s-1 e a concentração de saída de A 0,9 molL-1.
O resultado, referente ao volume reacional necessário para conduzir esta
reação, é de 416,67 L.
Na Figura 9 é apresentada a janela do programa onde foram inseridos os
coeficientes estequiométricos para o exemplo em questão. Apesar de haver um
inerte na alimentação do reator, como este não participa da reação, o seu
coeficiente estequiométrico é zero.
Figura 9 – Janela apresentando os coeficientes estequiométricos referentes ao exemplo 2
Fonte: Autoria própria (2019).
Na Figura 10 é apresentada a última janela do programa, em que foram
inseridos os valores dos parâmetros do exemplo 2.
39
Figura 10 – Janela apresentando os dados referentes ao exemplo 2
Fonte: Autoria própria (2019).
Ao clicar no botão “Calcular” obtem-se o resultado do exemplo 2,
apresentado na Figura 11.
Figura 11 – Janela final apresentando os resultados referentes ao exemplo 2
Fonte: Autoria própria (2019).
40
O componente inerte, que não participa da reação, não deve alterar seu
valor de concentração, e, conforme calculado, não alterou.
Os exemplos mostrados foram apenas formas de utilização, mostrando
como utilizar o software. Porém o principal enfoque do programa é a sua utilização
para qualquer conjunto de incógnitas dentre aquelas presentes no software, para
qualquer reação química, desde que o número de componentes presentes no
processo/reação seja menor ou igual a 5, sempre levando em consideração as
hipóteses simplificadoras descritas no início da obtenção do modelo matemático.
41
6 CONCLUSÃO
Neste trabalho obteve-se um software para problemas de dimensionamento
de reatores CSTR operando isotermicamente, podendo envolver até cinco
componentes (incluindo os componentes inertes) no processo reacional. O grande
diferencial do software é a possibilidade de escolher um conjunto de incógnitas com
número igual ao número de componentes com os outros parâmetros devendo ter
seus valores especificados.
Foram apresentados os testes feitos com o software para resolver dois
casos simples, sendo que nestes casos o software, com o algoritmo utilizado que foi
desenvolvido em linguagem de programação Python, se mostrou eficiente. No
entanto, faz-se necessária a realização de teste complementares para explorar
melhor a capacidade do software desenvolvido.
O software pode ser utilizado em universidades por estudantes, professores
e pesquisadores. Pode ser usado em empresas por apresentar uma interface
intuitiva e de fácil compreensão. A cada janela usada está uma nova explicação,
para que o usuário compreenda da melhor forma possível o que necessita ser feito e
ter o melhor aproveitamento do software.
Dessa forma, alcançou-se com sucesso o objetivo do trabalho, que era o
desenvolvimento de um software que resolvesse problemas de dimensionamento de
reatores do tipo CSTR.
Como é um programa em escala piloto, muito pode se aperfeiçoar, tanto em
questão de código, como em questão de interface gráfica.
Sugestões para trabalhos futuros seriam:
Trabalhar com a variável conversão, que descreve muito o
comportamento de uma reação;
Considerar reações em fase gasosa, levando em conta o fator de
expansividade volumétrica;
Supor variação na temperatura do processo, ou seja, trabalhar com
reator não isotérmico;
Considerar outras constantes para cálculo, como tempo espacial e
número de Damkhöler.
42
REFERÊNCIAS
BURDEN, R. L.; FAIRES, J. D.; BURDEN, A. M. Análise Numérica. 3. ed. São Paulo: Cengage Learning, 2015, p. 704. DUARTE, A. P. S.; ORELLANA, M. H. B.; CAMPOS, R. P. Uso do Software Livre Aplicado à Engenharia Química. Departamento de Engenharia Química, Universidade Federal de Minas Gerais, Belo Horizonte, 2011. FOGLER, H. S. Cálculo de Reatores: O Essencial da Engenharia das Reações Químicas. 1. ed. Rio de Janeiro: LTC, 2014, p. 6-11. HIMMELBLAU, D. M.; RIGGS, J. B. Engenharia Química: Princípios e Cálculos. 8. ed. Rio de Janeiro: LTC, 2014, p. 91-95. LEVENSPIEL, O. Engenharia das Reações Químicas. 3. ed. São Paulo: Blucher, 2000, p. 4-5. MONGELLI, L. T. Indústria 4.0 e suas principais características. BetaEQ. 2019. Disponível em: <https://betaeq.com.br/index.php/2019/11/04/industria-4-o-e-suas-principais-caracteristicas/>. Acesso em: 12 nov. 2019. PERKOVIC, L. Introdução à Computação usando Python: um foco no desenvolvimento de aplicações. 1. ed. Rio de Janeiro: LTC, 2016, p. 8. PINTO, J. C.; LAGE, P. L. C. Métodos Numéricos em Problemas de Engenharia Química. Rio de Janeiro: E-papers Serviços Editoriais Ltda, 2001, p. 64. ROBERTS, G. W. Reações Químicas e Reatores Químicos. 1. ed. Rio de Janeiro: LTC, 2010, p. 16-23. RUGGIERO, M. A. G.; LOPES, V. L. R. Cálculo Numérico: Aspectos teóricos e computacionais. 2. ed. São Paulo: Pearson Makron Books, 1996, p. 192-200. RUSSEL, J. B. Química Geral. 2. ed. São Paulo: Pearson Makron Books, 1994, p. 16. SANTANA, L. Por que o Python é considerado a melhor linguagem de programação à frente do JavaScript e do C++? Sempre Update. 2019. Disponível em: <https://sempreupdate.com.br/por-que-o-python-e-considerado-a-melhor-linguagem-de-programacao-a-frente-do-javascript-e-do-c/>. Acesso em: 26 nov. 2019. SANTOS, T. M. Um Estudo sobre a Resolução de Sistemas não Lineares: Perspectivas Teóricas e Aplicações. 2016. 116 f. Tese (Doutorado em Matemática Aplicada) – Universidade Estadual de Campinas, Campinas, 2016.
43
VAZ, W. Saiba mais como o python surgiu e qual o cenário agora. Eu sou DEV, 2018. Acesso em: < https://eusoudev.com.br/python-como-surgiu/>. Acesso em: 10 jun. 2019. VIEIRA, Gilberto. Qual a Importância dos Softwares de Automação para Engenheiros? Blog dos Engenheiros, 2018. Disponível em: <http://blogdosengenheiros.com.br/importancia-dos-softwares-de-automacao-para-engenheiros/>. Acesso em: 04 maio. 2019.
44
APÊNDICE A – CÓDIGO PYTHON
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
import numpy as np
from Broyden import Broyden_method
class FirstWindow(Screen):
pass
class FifthWindow(Screen):
pass
class ThirdWindow(Screen):
def scan2(self, g):
global nu_val
nu1 = self.nu1.text
nu2 = self.nu2.text
nu3 = self.nu3.text
nu4 = self.nu4.text
nu5 = self.nu5.text
nu_val = []
nu_var = []
#nu1
if nu1 == 'nu1' or nu1 == 'NU1' or nu1 == '':
nu_var.append('nu1')
45
else:
try:
nu_val.append(float(nu1))
except:
self.nu1.text = 'nu1'
self.nu2.text = 'nu2'
self.nu3.text = 'nu3'
self.nu4.text = 'nu4'
self.nu5.text = 'nu5'
# nu2
if nu2 == 'nu2' or nu2 == 'NU2' or nu2 == '':
nu_var.append('nu2')
else:
try:
nu_val.append(float(nu2))
except:
self.nu1.text = 'nu1'
self.nu2.text = 'nu2'
self.nu3.text = 'nu3'
self.nu4.text = 'nu4'
self.nu5.text = 'nu5'
# nu3
if nu3 == 'nu3' or nu3 == 'NU3' or nu3 == '':
nu_var.append('nu3')
else:
try:
nu_val.append(float(nu3))
except:
46
self.nu1.text = 'nu1'
self.nu2.text = 'nu2'
self.nu3.text = 'nu3'
self.nu4.text = 'nu4'
self.nu5.text = 'nu5'
# nu4
if nu4 == 'nu4' or nu4 == 'NU4' or nu4 == '':
nu_var.append('nu4')
else:
try:
nu_val.append(float(nu4))
except:
self.nu1.text = 'nu1'
self.nu2.text = 'nu2'
self.nu3.text = 'nu3'
self.nu4.text = 'nu4'
self.nu5.text = 'nu5'
#nu5
if nu5 == 'nu5' or nu5 == 'NU5' or nu5 == '':
nu_var.append('nu5')
else:
try:
nu_val.append(float(nu5))
except:
self.nu1.text = 'nu1'
self.nu2.text = 'nu2'
self.nu3.text = 'nu3'
47
self.nu4.text = 'nu4'
self.nu5.text = 'nu5'
print(nu_val)
print(nu_var)
class SecondWindow(Screen):
def scann(self, a):
global v_val, v_var, index_val, index_var
v = self.v.text
u = self.u.text
k = self.k.text
kc = self.kc.text
ca0 = self.ca0.text
cb0 = self.cb0.text
cc0 = self.cc0.text
cd0 = self.cd0.text
ce0 = self.ce0.text
ca = self.ca.text
cb = self.cb.text
cc = self.cc.text
cd = self.cd.text
ce = self.ce.text
v_val = []
v_var = []
index_val = []
index_var = []
48
#volume
if v == 'v' or v == 'V' or v == '':
v_var.append('V')
index_var.append(0)
print("Não tem valor em V")
else:
try:
v_val.append(float(v))
index_val.append(0)
print(v_val[0])
except:
self.v.text = 'V'
self.u.text = 'u'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
print('Não deu certo')
#vazao
if u == 'U' or u == 'u' or u == '':
v_var.append('u')
49
index_var.append(1)
print("Não tem valor em u")
else:
try:
v_val.append(float(u))
index_val.append(1)
print("Veio aki")
except:
self.v.text = 'V'
self.u.text = 'u'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#constante cinetica k
if k == 'k' or k == 'K' or k == '':
v_var.append('k')
index_var.append(2)
print("Não tem valor em k")
else:
50
try:
v_val.append(float(k))
index_val.append(2)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#constante de equilibrio
if kc == 'Kc' or kc == 'KC' or kc == '':
v_var.append('kc')
index_var.append(3)
print("Não tem valor em Kc")
else:
try:
v_val.append(float(kc))
index_val.append(3)
except:
self.v.text = 'V'
51
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Entrada A
if ca0 == 'Ca0' or ca0 == 'CA0' or ca0 == '':
v_var.append('ca0')
index_var.append(4)
print("Não tem valor em Ca0")
else:
try:
v_val.append(float(ca0))
index_val.append(4)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
52
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Entrada B
if cb0 == 'Cb0' or cb0 == 'CB0' or cb0 == '':
v_var.append('cb0')
index_var.append(5)
print("Não tem valor em Cb0")
else:
try:
v_val.append(float(cb0))
index_val.append(5)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
53
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Entrada C
if cc0 == 'Cc0' or cc0 == 'CC0' or cc0 == '':
v_var.append('cc0')
index_var.append(6)
print("Não tem valor em Cc0")
else:
try:
v_val.append(float(cc0))
index_val.append(6)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Entrada D
54
if cd0 == 'Cd0' or cd0 == 'CD0' or cd0 == '':
v_var.append('cd0')
index_var.append(7)
print("Não tem valor em Cd0")
else:
try:
v_val.append(float(cd0))
index_val.append(7)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
# Entrada E
if ce0 == 'Ce0' or ce0 == 'CE0' or ce0 == '':
v_var.append('ce0')
index_var.append(8)
print("Não tem valor em Ce0")
else:
55
try:
v_val.append(float(ce0))
index_val.append(8)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Saida A
if ca == 'Ca' or ca == 'CA' or ca == '':
v_var.append('ca')
index_var.append(9)
print("Não tem valor em Ca")
else:
try:
v_val.append(float(ca))
index_val.append(9)
except:
self.v.text = 'V'
56
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Saida B
if cb == 'Cb' or cb == 'CB' or cb == '':
v_var.append('cb')
index_var.append(10)
print("Não tem valor em Cb")
else:
try:
v_val.append(float(cb))
index_val.append(10)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
57
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Saida C
if cc == 'Cc' or cc == 'CC' or cc == '':
v_var.append('cc')
index_var.append(11)
print("Não tem valor em Cc")
else:
try:
v_val.append(float(cc))
index_val.append(11)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
58
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
#Saida D
if cd == 'Cd' or cd == 'CD' or cd == '':
v_var.append('cd')
index_var.append(12)
print("Não tem valor em Cd")
else:
try:
v_val.append(float(cd))
index_val.append(12)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
# Saida E
59
if ce == 'Ce' or ce == 'CE' or ce == '':
v_var.append('ce')
index_var.append(13)
print("Não tem valor em Ce")
else:
try:
v_val.append(float(ce))
index_val.append(13)
except:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
if len(v_val) != 9 or len(v_var) != 5 or v_val[0] < 0 or v_val[1] < 0 or v_val[2] < 0
or v_val[3] < 0:
self.v.text = 'V'
self.u.text = 'v'
self.k.text = 'k'
self.kc.text = 'Kc'
self.ca0.text = 'Ca0'
60
self.cb0.text = 'Cb0'
self.cc0.text = 'Cc0'
self.cd0.text = 'Cd0'
self.ce0.text = 'Ce0'
self.ca.text = 'Ca'
self.cb.text = 'Cb'
self.cc.text = 'Cc'
self.cd.text = 'Cd'
self.ce.text = 'Ce'
self.status.text = 'Número incorreto de valores inseridos.'
print('Não deu certo antes do CSTR')
print(len(v_val), len(v_var))
print(v_var)
print(index_var)
else:
print(index_var)
print(index_val)
print(len(index_var))
print(nu_val)
print(v_val)
# try:
def CSTR(X, N):
global nu_val, Fix_index, X_fix, v_val, v_var, index_val, index_var, N_fix
X_fix = np.array([v_val[0], v_val[1], v_val[2], v_val[3], v_val[4], v_val[5],
v_val[6], v_val[7], v_val[8]])
N_fix = 9 # nº valores fixos
61
C = np.zeros(N)
C0 = np.zeros(N)
eq = np.zeros(N)
Y = np.zeros(N + N_fix)
for i in range(0, N):
Y[index_var[i]] = X[i]
for i in range(0, N_fix):
Y[index_val[i]] = X_fix[i]
v = Y[0]
u = Y[1]
k = Y[2]
kc = Y[3]
for j in range(0, N):
C0[j] = Y[j + 4] # pq j comeca em 0
C[j] = Y[j + 9]
prod1 = 1.0
prod2 = 1.0
for j in range(0, N):
prod1 = prod1 * C[j] ** ((abs(nu_val[j]) - nu_val[j]) / 2) # Produtório
reagentes
prod2 = prod2 * C[j] ** ((abs(nu_val[j]) + nu_val[j]) / 2) # Produtório
produtos
r = k * (prod1 - (prod2 / kc))
for j in range(0, N):
62
eq[j] = (u / v) * (C0[j] - C[j]) + nu_val[j] * r
return eq
X0= np.array([1.0, 1.0, 1.0, 1.0, 1.0])
N_inc = 5 # nº incog vai ser igual ao nº variav
res = Broyden_method(CSTR, N_inc, X0, MaxIter=10000, h=1e-10, Tol=1e-
8)
print(res)
if index_var[0] == 0:
self.v.text = str(round((res["X_sol"][0]), 3))
self.v.background_color = (0, 1, 0, 1)
elif index_var[0] == 1:
self.u.text = str(round((res["X_sol"][0]), 3))
self.u.background_color = (0, 1, 0, 1)
elif index_var[0] == 2:
self.k.text = str(round((res["X_sol"][0]), 3))
self.k.background_color = (0, 1, 0, 1)
elif index_var[0] == 3:
self.kc.text = str(round((res["X_sol"][0]), 3))
self.kc.background_color = (0, 1, 0, 1)
elif index_var[0] == 4:
self.ca0.text = str(round((res["X_sol"][0]), 3))
self.ca0.background_color = (0, 1, 0, 1)
elif index_var[0] == 5:
self.cb0.text = str(round((res["X_sol"][0]), 3))
self.cb0.background_color = (0, 1, 0, 1)
elif index_var[0] == 6:
self.cc0.text = str(round((res["X_sol"][0]), 3))
self.cc0.background_color = (0, 1, 0, 1)
63
elif index_var[0] == 7:
self.cd0.text = str(round((res["X_sol"][0]), 3))
self.cd0.background_color = (0, 1, 0, 1)
elif index_var[0] == 8:
self.ce0.text = str(round((res["X_sol"][0]), 3))
self.ce0.background_color = (0, 1, 0, 1)
elif index_var[0] == 9:
self.ca.text = str(round((res["X_sol"][0]), 3))
self.ca.background_color = (0, 1, 0, 1)
elif index_var[0] == 10:
self.cb.text = str(round((res["X_sol"][0]), 3))
self.cb.background_color = (0, 1, 0, 1)
elif index_var[0] == 11:
self.cc.text = str(round((res["X_sol"][0]), 3))
self.cc.background_color = (0, 1, 0, 1)
elif index_var[0] == 12:
self.cd.text = str(round((res["X_sol"][0]), 3))
self.cd.background_color = (0, 1, 0, 1)
elif index_var[0] == 13:
self.ce.text = str(round((res["X_sol"][0]), 3))
self.ce.background_color = (0, 1, 0, 1)
if index_var[1] == 0:
self.v.text = str(round((res["X_sol"][1]), 3))
self.v.background_color = (0, 1, 0, 1)
elif index_var[1] == 1:
self.u.text = str(round((res["X_sol"][1]), 3))
self.u.background_color = (0, 1, 0, 1)
elif index_var[1] == 2:
self.k.text = str(round((res["X_sol"][1]), 3))
64
self.k.background_color = (0, 1, 0, 1)
elif index_var[1] == 3:
self.kc.text = str(round((res["X_sol"][1]), 3))
self.kc.background_color = (0, 1, 0, 1)
elif index_var[1] == 4:
self.ca0.text = str(round((res["X_sol"][1]), 3))
self.ca0.background_color = (0, 1, 0, 1)
elif index_var[1] == 5:
self.cb0.text = str(round((res["X_sol"][1]), 3))
self.cb0.background_color = (0, 1, 0, 1)
elif index_var[1] == 6:
self.cc0.text = str(round((res["X_sol"][1]), 3))
self.cc0.background_color = (0, 1, 0, 1)
elif index_var[1] == 7:
self.cd0.text = str(round((res["X_sol"][1]), 3))
self.cd0.background_color = (0, 1, 0, 1)
elif index_var[1] == 8:
self.ce0.text = str(round((res["X_sol"][1]), 3))
self.ce0.background_color = (0, 1, 0, 1)
elif index_var[1] == 9:
self.ca.text = str(round((res["X_sol"][1]), 3))
self.ca.background_color = (0, 1, 0, 1)
elif index_var[1] == 10:
self.cb.text = str(round((res["X_sol"][1]), 3))
self.cb.background_color = (0, 1, 0, 1)
elif index_var[1] == 11:
self.cc.text = str(round((res["X_sol"][1]), 3))
self.cc.background_color = (0, 1, 0, 1)
elif index_var[1] == 12:
self.cd.text = str(round((res["X_sol"][1]), 3))
65
self.cd.background_color = (0, 1, 0, 1)
elif index_var[1] == 13:
self.ce.text = str(round((res["X_sol"][1]), 3))
self.ce.background_color = (0, 1, 0, 1)
if index_var[2] == 0:
self.v.text = str(round((res["X_sol"][2]), 3))
self.v.background_color = (0, 1, 0, 1)
elif index_var[2] == 1:
self.u.text = str(round((res["X_sol"][2]), 3))
self.u.background_color = (0, 1, 0, 1)
elif index_var[2] == 2:
self.k.text = str(round((res["X_sol"][2]), 3))
self.k.background_color = (0, 1, 0, 1)
elif index_var[2] == 3:
self.kc.text = str(round((res["X_sol"][2]), 3))
self.kc.background_color = (0, 1, 0, 1)
elif index_var[2] == 4:
self.ca0.text = str(round((res["X_sol"][2]), 3))
self.ca0.background_color = (0, 1, 0, 1)
elif index_var[2] == 5:
self.cb0.text = str(round((res["X_sol"][2]), 3))
self.cb0.background_color = (0, 1, 0, 1)
elif index_var[2] == 6:
self.cc0.text = str(round((res["X_sol"][2]), 3))
self.cc0.background_color = (0, 1, 0, 1)
elif index_var[2] == 7:
self.cd0.text = str(round((res["X_sol"][2]), 3))
self.cd0.background_color = (0, 1, 0, 1)
elif index_var[2] == 8:
66
self.ce0.text = str(round((res["X_sol"][2]), 3))
self.ce0.background_color = (0, 1, 0, 1)
elif index_var[2] == 9:
self.ca.text = str(round((res["X_sol"][2]), 3))
self.ca.background_color = (0, 1, 0, 1)
elif index_var[2] == 10:
self.cb.text = str(round((res["X_sol"][2]), 3))
self.cb.background_color = (0, 1, 0, 1)
elif index_var[2] == 11:
self.cc.text = str(round((res["X_sol"][2]), 3))
self.cc.background_color = (0, 1, 0, 1)
elif index_var[2] == 12:
self.cd.text = str(round((res["X_sol"][2]), 3))
self.cd.background_color = (0, 1, 0, 1)
elif index_var[2] == 13:
self.ce.text = str(round((res["X_sol"][2]), 3))
self.ce.background_color = (0, 1, 0, 1)
if index_var[3] == 0:
self.v.text = str(round((res["X_sol"][3]), 3))
self.v.background_color = (0, 1, 0, 1)
elif index_var[3] == 1:
self.u.text = str(round((res["X_sol"][3]), 3))
self.u.background_color = (0, 1, 0, 1)
elif index_var[3] == 2:
self.k.text = str(round((res["X_sol"][3]), 3))
self.k.background_color = (0, 1, 0, 1)
elif index_var[3] == 3:
self.kc.text = str(round((res["X_sol"][3]), 3))
self.kc.background_color = (0, 1, 0, 1)
67
elif index_var[3] == 4:
self.ca0.text = str(round((res["X_sol"][3]), 3))
self.ca0.background_color = (0, 1, 0, 1)
elif index_var[3] == 5:
self.cb0.text = str(round((res["X_sol"][3]), 3))
self.cb0.background_color = (0, 1, 0, 1)
elif index_var[3] == 6:
self.cc0.text = str(round((res["X_sol"][3]), 3))
self.cc0.background_color = (0, 1, 0, 1)
elif index_var[3] == 7:
self.cd0.text = str(round((res["X_sol"][3]), 3))
self.cd0.background_color = (0, 1, 0, 1)
elif index_var[3] == 8:
self.ce0.text = str(round((res["X_sol"][3]), 3))
self.ce0.background_color = (0, 1, 0, 1)
elif index_var[3] == 9:
self.ca.text = str(round((res["X_sol"][3]), 3))
self.ca.background_color = (0, 1, 0, 1)
elif index_var[3] == 10:
self.cb.text = str(round((res["X_sol"][3]), 3))
self.cb.background_color = (0, 1, 0, 1)
elif index_var[3] == 11:
self.cc.text = str(round((res["X_sol"][3]), 3))
self.cc.background_color = (0, 1, 0, 1)
elif index_var[3] == 12:
self.cd.text = str(round((res["X_sol"][3]), 3))
self.cd.background_color = (0, 1, 0, 1)
elif index_var[3] == 13:
self.ce.text = str(round((res["X_sol"][3]), 3))
self.ce.background_color = (0, 1, 0, 1)
68
if index_var[4] == 0:
self.v.text = str(round((res["X_sol"][4]), 3))
self.v.background_color = (0, 1, 0, 1)
elif index_var[4] == 1:
self.u.text = str(round((res["X_sol"][4]), 3))
self.u.background_color = (0, 1, 0, 1)
elif index_var[4] == 2:
self.k.text = str(round((res["X_sol"][4]), 3))
self.k.background_color = (0, 1, 0, 1)
elif index_var[4] == 3:
self.kc.text = str(round((res["X_sol"][4]), 3))
self.kc.background_color = (0, 1, 0, 1)
elif index_var[4] == 4:
self.ca0.text = str(round((res["X_sol"][4]), 3))
self.ca0.background_color = (0, 1, 0, 1)
elif index_var[4] == 5:
self.cb0.text = str(round((res["X_sol"][4]), 3))
self.cb0.background_color = (0, 1, 0, 1)
elif index_var[4] == 6:
self.cc0.text = str(round((res["X_sol"][4]), 3))
self.cc0.background_color = (0, 1, 0, 1)
elif index_var[4] == 7:
self.cd0.text = str(round((res["X_sol"][4]), 3))
self.cd0.background_color = (0, 1, 0, 1)
elif index_var[4] == 8:
self.ce0.text = str(round((res["X_sol"][4]), 3))
self.ce0.background_color = (0, 1, 0, 1)
elif index_var[4] == 9:
self.ca.text = str(round((res["X_sol"][4]), 3))
69
self.ca.background_color = (0, 1, 0, 1)
elif index_var[4] == 10:
self.cb.text = str(round((res["X_sol"][4]), 3))
self.cb.background_color = (0, 1, 0, 1)
elif index_var[4] == 11:
self.cc.text = str(round((res["X_sol"][4]), 3))
self.cc.background_color = (0, 1, 0, 1)
elif index_var[4] == 12:
self.cd.text = str(round((res["X_sol"][4]), 3))
self.cd.background_color = (0, 1, 0, 1)
elif index_var[4] == 13:
self.ce.text = str(round((res["X_sol"][4]), 3))
self.ce.background_color = (0, 1, 0, 1)
if res["Message"] == 'Problem solved sucessfully!':
self.status.text = 'Problema resolvido!!!'
else:
self.v.text = ':('
self.v.background_color = (1, 1, 1, 1)
self.u.text = ':('
self.u.background_color = (1, 1, 1, 1)
self.k.text = ':('
self.k.background_color = (1, 1, 1, 1)
self.kc.text = ':('
self.kc.background_color = (1, 1, 1, 1)
self.ca0.text = ':('
self.ca0.background_color = (1, 1, 1, 1)
self.cb0.text = ':('
self.cb0.background_color = (1, 1, 1, 1)
self.cc0.text = ':('
70
self.cc0.background_color = (1, 1, 1, 1)
self.cd0.text = ':('
self.cd0.background_color = (1, 1, 1, 1)
self.ce0.text = ':('
self.ce0.background_color = (1, 1, 1, 1)
self.ca.text = ':('
self.ca.background_color = (1, 1, 1, 1)
self.cb.text = ':('
self.cb.background_color = (1, 1, 1, 1)
self.cc.text = ':('
self.cc.background_color = (1, 1, 1, 1)
self.cd.text = ':('
self.cd.background_color = (1, 1, 1, 1)
self.ce.text = ':('
self.ce.background_color = (1, 1, 1, 1)
self.status.text = 'Verifique os valores inseridos!!'
print('Não deu certo!')
def limpar(self, d):
self.v.text = 'V'
self.v.background_color = (1, 1, 1, 1)
self.u.text = 'u'
self.u.background_color = (1, 1, 1, 1)
self.k.text = 'k'
self.k.background_color = (1, 1, 1, 1)
self.kc.text = 'Kc'
self.kc.background_color = (1, 1, 1, 1)
self.ca0.text = 'Ca0'
self.ca0.background_color = (1, 1, 1, 1)
self.cb0.text = 'Cb0'
71
self.cb0.background_color = (1, 1, 1, 1)
self.cc0.text = 'Cc0'
self.cc0.background_color = (1, 1, 1, 1)
self.cd0.text = 'Cd0'
self.cd0.background_color = (1, 1, 1, 1)
self.ce0.text = 'Ce0'
self.ce0.background_color = (1, 1, 1, 1)
self.ca.text = 'Ca'
self.ca.background_color = (1, 1, 1, 1)
self.cb.text = 'Cb'
self.cb.background_color = (1, 1, 1, 1)
self.cc.text = 'Cc'
self.cc.background_color = (1, 1, 1, 1)
self.cd.text = 'Cd'
self.cd.background_color = (1, 1, 1, 1)
self.ce.text = 'Ce'
self.ce.background_color = (1, 1, 1, 1)
self.status.text = ''
class WindowManagement(ScreenManager):
pass
kv = Builder.load_file("cstri.kv")
class MyMainApp(App):
def build(self):
return kv
if __name__ == "__main__":
72
MyMainApp().run()
73
APÊNDICE B – CÓDIGO KIVY
WindowManagement:
FirstWindow:
FifthWindow:
ThirdWindow:
SecondWindow:
<FirstWindow>
name:"First Window"
GridLayout:
cols:1
Label:
text:"Software para resolução de \nProblemas de dimensionamento de
CSTR"
halign: 'center'
font_size: 40
FloatLayout:
Button:
text: "Iniciar"
pos_hint: {"x":0.8, "y":0}
size_hint: 0.2,0.15
font_size:20
on_press:
app.root.current = "Fifth Window"
<FifthWindow>
name:"Fifth Window"
GridLayout:
cols:1
row:4
GridLayout:
cols:1
GridLayout:
74
cols:1
Label:
text:"Este software resolve problemas com\nno máximo 5
componentes.\nCaso seu problema possua\nmenos de 5 componentes, os
valores\ndos coeficientes estequiométricos daqueles\nque não existem devem ser '0'
e os valores\ndas concentrações de entrada deverão ser\nfixados em '0'."
halign: 'center'
font_size: 20
GridLayout:
cols:1
Label:
text:"Para que o programa consiga realizar o cálculo,\ndeve ser fornecido
um total de 9 valores."
halign:'center'
font_size: 20
GridLayout:
cols:1
Label:
text:"Caso a reação seja irreversível,\n utilize um alto valor para a
constante de equilíbrio Kc.\n(Ex: 1000000000)"
halign:'center'
font_size: 20
FloatLayout:
Button:
text: "Próximo"
pos_hint: {"x":0.8, "y":0}
size_hint: 0.2,0.3
font_size:20
on_press:
app.root.current = "Third Window"
<ThirdWindow>
nu1: nu1.__self__
75
nu2: nu2.__self__
nu3: nu3.__self__
nu4: nu4.__self__
nu5: nu5.__self__
name: 'Third Window'
GridLayout:
row:5
cols:2
Label:
text: "Insira os coeficientes\nestequiométricos"
font_size: 30
halign: 'center'
Label:
text: "(Obs: Lembrar que reagentes\npossuem coeficiente negativo e\ninertes
possuem coeficiente nulo.)"
font_size: 15
halign: 'center'
Label:
text: "Componente 1"
font_size: 20
TextInput:
id: nu1
Label:
text: "Componente 2"
font_size: 20
TextInput:
id: nu2
Label:
76
text: "Componente 3"
font_size: 20
TextInput:
id: nu3
Label:
text: "Componente 4"
font_size: 20
TextInput:
id: nu4
Label:
text: "Componente 5"
font_size: 20
TextInput:
id: nu5
GridLayout:
cols:1
Button
text:"Próximo"
font_size:20
on_press:
root.scan2(*args)
app.root.current = "Second Window"
<SecondWindow>
v: v.__self__
u: u.__self__
k: k.__self__
kc: kc.__self__
ca0: ca0.__self__
77
cb0: cb0.__self__
cc0: cc0.__self__
cd0: cd0.__self__
ce0: ce0.__self__
ca: ca.__self__
cb: cb.__self__
cc: cc.__self__
cd: cd.__self__
ce: ce.__self__
status: status.__self__
name:"Second Window"
GridLayout:
rows:13
GridLayout:
cols:2
Label:
text: "V: "
font_size: 20
color: 1,1,1,1
TextInput:
id:v
text: 'V'
multiline: False
Label:
text: "\u03C5: "
font_size: 20
color: 1,1,1,1
TextInput:
id:u
text: 'u'
multiline: False
78
Label:
text: "k: "
font_size: 20
color: 1,1,1,1
TextInput:
id:k
text: 'k'
multiline: False
Label:
text: "Kc: "
font_size: 20
color: 1,1,1,1
TextInput:
id:kc
text: 'Kc'
multiline: False
Label:
text: "Ca0: "
font_size: 20
color: 1,1,1,1
TextInput:
id:ca0
text:'Ca0'
multiline: False
Label:
text: "Cb0: "
font_size: 20
color: 1,1,1,1
TextInput:
id:cb0
79
text: 'Cb0'
multiline: False
Label:
text: "Cc0: "
font_size: 20
color: 1,1,1,1
TextInput:
id:cc0
text: 'Cc0'
multiline: False
Label:
text: "Cd0: "
font_size: 20
color: 1,1,1,1
TextInput:
id:cd0
text: 'Cd0'
multiline: False
Label:
text: "Ce0: "
font_size: 20
color: 1,1,1,1
TextInput:
id:ce0
text: 'Ce0'
multiline: False
Label:
text: "Ca: "
font_size: 20
color: 1,1,1,1
80
TextInput:
id:ca
text: 'Ca'
multiline: False
Label:
text: "Cb: "
font_size: 20
color: 1,1,1,1
TextInput:
id:cb
text: 'Cb'
multiline: False
Label:
text: "Cc: "
font_size: 20
color: 1,1,1,1
TextInput:
id:cc
text: 'Cc'
multiline: False
Label:
text: "Cd: "
font_size: 20
color: 1,1,1,1
TextInput:
id:cd
text: 'Cd'
multiline: False
Label:
text: "Ce: "
81
font_size: 20
color: 1,1,1,1
TextInput:
id:ce
text: 'Ce'
multiline: False
GridLayout:
cols:2
Button
text:"Calcular"
font_size:20
on_press:
root.scann(*args)
Button:
text: "Limpar"
font_size:20
on_press:
root.limpar(*args)
Label:
id: status
text: ''
halign: 'center'
font_size:20
top related