Reactors in Python#

This week we will see how to address problems that you have previously been solving by hand, in Python.

Ideal batch reactor (week 1)#

Problem A:#

In an ideal batch reactor, the following reaction takes place \(A → Products\)

with a rate expression of: \(R = -r_{A}=k{C_{A}}^n \)

The reactor is isothermal and the density of the reaction mixture is constant. The reaction starts at time t = 0, where the concentration of A is \(C_{A0}\).

After a reaction time of 1 hour, the concentration of A is measured to be: \(\frac{C_{A}}{C_{A0}}=0.1\)

  1. Calculate the rate constant and how much longer the reaction must continue to obtain \(\frac{C_{A}}{C_{A0}}=0.001\) a. For a first order reaction, n = 1 b. For a second order reaction, n = 2 (In this case it is not possible to calculate the rate constant \(kC_{A0}\), but can be calculated and used to estimate how much longer the reaction must continue to obtain \(\frac{C_{A}}{C_{A0}}=0.001\))

Solving the first order reaction#

# in the code we can make a loop to check whether the V is constant
# otherwise print something
# this might help you in the future
import numpy as np

def first_order_reaction_batch(C_ratio, t, V='constant'):
    '''
    Given the solved equation for an ideal batch reactor and the time, 
    this function returns the rate constant for a first order reaction.
    Args:
        C_ratio (float): Concentration of A, given by CA/CA0 ratio.
        t (int): time necessary to reach given concentration of A.
    returns:
        k (float): rate constant.
    '''
    if V == 'constant':   
        k = -np.log(C_ratio)/t
    else:
        print('V should be constant in this exercise')         
    return k

def first_order_time(C_ratio, k):
    '''
    Given the solved equation for an ideal batch reactor 
    and the previously calculated rate constant, 
    this function returns the time (how much longer the reaction 
    must continue to obtain CA/CA0 = 0.001).
    
    Args:
        C_ratio (float): Concentration of A, given by CA/CA0 ratio.
        k (float): rate constant.
    returns:
        t (int): time necessary to reach given concentration of A.
    '''
    t = -np.log(C_ratio)/k
    return round(t)
    
t1 = 1
CA_CA0_1h = 0.1
CA_CA0_t = 0.001
k_first_order = first_order_reaction_batch(CA_CA0_1h, t1)
print(f'The rate constant is: {round(k_first_order, 2)}')
t2 = first_order_time(CA_CA0_t, k_first_order)

time = t2 - t1
print(f"Time needed to reach given concentration of A is: {time} hours")
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[1], line 4
      1 # in the code we can make a loop to check whether the V is constant
      2 # otherwise print something
      3 # this might help you in the future
----> 4 import numpy as np
      6 def first_order_reaction_batch(C_ratio, t, V='constant'):
      7     '''
      8     Given the solved equation for an ideal batch reactor and the time, 
      9     this function returns the rate constant for a first order reaction.
   (...)
     14         k (float): rate constant.
     15     '''

ModuleNotFoundError: No module named 'numpy'

Solving the second order reaction#

def second_order_reaction_batch(C_ratio, t, V='constant'):
    if V == 'constant':
        k_CA0 = 1/t*(1/C_ratio - 1)
    else:
        print('V should be constant in this exercise')         
    return k_CA0

def second_order_time(C_ratio, k):
    return 1/k*(1/C_ratio -1)

k_second_order = second_order_reaction_batch(CA_CA0_1h, t1)
print(f'The rate constant is: {k_second_order}')
t2 = second_order_time(CA_CA0_t, k_second_order)

time = t2 - t1
print(f"Time needed to reach given concentration of A is: {time} hours")
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[2], line 11
      8 def second_order_time(C_ratio, k):
      9     return 1/k*(1/C_ratio -1)
---> 11 k_second_order = second_order_reaction_batch(CA_CA0_1h, t1)
     12 print(f'The rate constant is: {k_second_order}')
     13 t2 = second_order_time(CA_CA0_t, k_second_order)

NameError: name 'CA_CA0_1h' is not defined

Putting it all together.

def reaction_batch(C_ratio, t, order):
    
    if order == 'first':
        k = -np.log(C_ratio)/t
        
    elif order == 'second':
        k = 1/t*(1/C_ratio - 1)
        
    else:
        print('Provide the order of the reaction as a string')
        
    return k

def calculate_time(C_ratio, k, order):
    
    if order == 'first':
        t = -np.log(C_ratio)/k
        
    elif order == 'second':
        t = 1/k*(1/C_ratio -1)
    
    else:
        print('Provide the order of the reaction as a string')
        
    return round(t, 2)

print('Rate constant and time for first order batch reaction:')
k_first_order = reaction_batch(CA_CA0_1h, t1, 'first')
print(k_first_order)
print(calculate_time(CA_CA0_t, k_first_order, 'first')-t1)
print()
print('Rate constant and time for second order batch reaction:')
k_second_order = reaction_batch(CA_CA0_1h, t1, 'second')
print(k_second_order)
print(calculate_time(CA_CA0_t, k_second_order, 'second')-t1)
Rate constant and time for first order batch reaction:
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[3], line 28
     25     return round(t, 2)
     27 print('Rate constant and time for first order batch reaction:')
---> 28 k_first_order = reaction_batch(CA_CA0_1h, t1, 'first')
     29 print(k_first_order)
     30 print(calculate_time(CA_CA0_t, k_first_order, 'first')-t1)

NameError: name 'CA_CA0_1h' is not defined

Residence time in a CSTR#

  1. What should be the residence time, \(\tau = V/v_{0}\), in a CSTR to achieve \(\frac{C_{A}}{C_{A0}}=0.001\) for the reaction for each of the two cases: n = 1 and n = 2.

def first_order_reaction_CSTR(C_ratio, k, density='constant'):
    if density == 'constant':
        tau = 1/k*((1-C_ratio)/C_ratio)
    else: 
        print('Density should be constant in this exercise')
    return round(tau)

print(f'The residence time in a CSTR with n=1 is: {first_order_reaction_CSTR(CA_CA0_t, k_first_order)} h')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[4], line 8
      5         print('Density should be constant in this exercise')
      6     return round(tau)
----> 8 print(f'The residence time in a CSTR with n=1 is: {first_order_reaction_CSTR(CA_CA0_t, k_first_order)} h')

NameError: name 'CA_CA0_t' is not defined
def second_order_reaction_CSTR(C_ratio, k, density='constant'):
    if density == 'constant':
        tau = (1/k)*((1-C_ratio)/C_ratio**2)
    else: 
        print('Density should be constant in this exercise')
    return round(tau)

print(f'The residence time in a CSTR with n=2 is: {second_order_reaction_CSTR(CA_CA0_t, k_second_order)} h')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 8
      5         print('Density should be constant in this exercise')
      6     return round(tau)
----> 8 print(f'The residence time in a CSTR with n=2 is: {second_order_reaction_CSTR(CA_CA0_t, k_second_order)} h')

NameError: name 'CA_CA0_t' is not defined

Exercise: write a function to combine the first and second order reaction for CSTR (as done before for batch reactor).

Level: Medium.

# Your code here
  1. How would you explain the observed difference between a first order and a second order reaction in words?

# Type here