Modeling IEC using SMA and GRM

Hello everyone,

New to CADET here, I work as a downstream processing specialist particularly Monoclonals purification. I am trying to first understand CADET’s architecture and i have successfully simulated adsorption using Langmuir and LumpedRateModelWithPores, However I am facing challenges modeling IEC using SMA, I followed the tutorial for one component and was able to reproduce chromatograms successfully but I wanted to simulate 3 components,

Since new users can’t upload attachments here is my code

from CADETProcess.processModel import ComponentSystem

from CADETProcess.processModel import StericMassAction

from CADETProcess.processModel import Inlet, LumpedRateModelWithPores, Outlet,GeneralRateModel

from CADETProcess.processModel import FlowSheet

from CADETProcess.processModel import Process

# %%

# Defining Components

componentSystem = ComponentSystem()

componentSystem.add_component('Salt')

componentSystem.add_component('Impurity A')

componentSystem.add_component('Product')

componentSystem.add_component('Impurity B')

# %%

inlet = Inlet(componentSystem,'inlet')

outlet = Outlet(componentSystem,'outlet')

column = GeneralRateModel(componentSystem,'column')

# %%

# mmodel.reference

model = StericMassAction(componentSystem,'model')

model.is_kinetic = True

model.steric_factor = [0,25.5,15.2,10.7]

model.characteristic_charge = [0,5.2,5.6,3.3]

model.adsorption_rate = [0,0.30,0.650,0.10]

model.desorption_rate = [0,1,1,1]

model.capacity = 400

# model =Langmuir(componentSystem,'model')

# model.is_kinetic = False

# model.adsorption_rate = [0.0329,0.0037,0.016]

# model.desorption_rate = [1,1,1]

# model.capacity = 100

# model.missing_parameters

# %%

column.missing_parameters

# %%

column.binding_model = model

column.length = 0.25

column.diameter = 0.0115

column.bed_porosity = 0.37

column.particle_radius = 4.5e-5

column.particle_porosity = 0.33

column.axial_dispersion = 2.0e-7

column.film_diffusion = [2.0e-5, 2.0e-7, 2.0e-7, 2.0e-7]

column.pore_diffusion = [7e-5, 1e-9,1e-9,1e-9]

column.surface_diffusion = [0.0, 0.0,0.0,0.0]

# column.q = [model.capacity,0,0,0]

column.check_required_parameters()

# %%

sheet = FlowSheet(componentSystem,'flow_sheet')

# %%

sheet.add_unit(inlet)

sheet.add_unit(column)

sheet.add_unit(outlet)

sheet.add_connection(inlet,column)

sheet.add_connection(column,outlet)

# %%

inlet.flow_rate = 2.88e-8

# %%

process = Process(sheet,'process')

# %%

# column.c = [0.1,0,0,0]

# process.add_event('equilibration','flow_sheet.inlet.c',[100,0,0,0],0)

process.add_event('equilibration','flow_sheet.inlet.c',[0.001,0,0,0],0)

process.add_event('feed_on','flow_sheet.inlet.c',[0.001,50,100,25],300)

process.add_event('feed_off','flow_sheet.inlet.c',[0.1,0,0,0],1500)

process.add_event('wash','flow_sheet.inlet.c',[5,0,0,0],3000)

# process.add_event('wash','flow_sheet.inlet.c',[1,0,0,0],301)

# process.add_event('gradient_start','flow_sheet.inlet.c',[[0.01,1/60],0,0,0],100)

# process.add_event('step_1','flow_sheet.inlet.c',[10,0,0,0],100)

# process.add_event('step_2','flow_sheet.inlet.c',[20,0,0,0],400)

# process.add_event('step_3','flow_sheet.inlet.c',[200,0,0,0],700)

process.cycle_time = 5000

# column.q = [model.capacity,0,0,0]

# %%

from CADETProcess.simulator import Cadet

simulator = Cadet()

# simulator.simulate(process)

# %%

process.plot_events()

# process.result()

# %%

result = simulator.simulate(process)

from CADETProcess.plotting import SecondaryAxis

sec = SecondaryAxis()

sec.components = ["Salt"]

sec.y_label = '$c_{salt}$'

# result.solution.outlet.outlet.plot()

# %%

result.solution.column.outlet.plot(secondary_axis=sec)

Code in bold is commented out , I tried simulating different events but the chromatogram shows that the salt elutes with the components which didn’t happen in the tutorial. I tried equilibration instead of predefining a concentration in the column and i tried both, all 3 peaks co-elute together with no separation albeit i tried varying adsorption… how should one go about this ?
Thank you in advance, :slight_smile:
I am sorry if my understanding or code is unclear but I just started this two weeks ago to use it for process development eventually.

1 Like

Hi yqabil
and a hearty welcome to the CADET community!

Sorry that it took some time to have a look here. Do you still require assistance on this issue? For me your simulation runs unexpectedly long, so I think there might be a general problem in the setup (or the parameters) here.

If it is a IEC with SMA and 3 components you are after, you might want to check the LWE Example in the Documentation for reference, which provides the following working example:

import numpy as np

from CADETProcess.processModel import ComponentSystem
from CADETProcess.processModel import StericMassAction
from CADETProcess.processModel import Inlet, GeneralRateModel, Outlet
from CADETProcess.processModel import FlowSheet
from CADETProcess.processModel import Process

# Component System
component_system = ComponentSystem()
component_system.add_component('Salt')
component_system.add_component('A')
component_system.add_component('B')
component_system.add_component('C')

# Binding Model
binding_model = StericMassAction(component_system, name='SMA')
binding_model.is_kinetic = True
binding_model.adsorption_rate = [0.0, 35.5, 1.59, 7.7]
binding_model.desorption_rate = [0.0, 1000, 1000, 1000]
binding_model.characteristic_charge = [0.0, 4.7, 5.29, 3.7]
binding_model.steric_factor = [0.0, 11.83, 10.6, 10]
binding_model.capacity = 1200.0

# Unit Operations
inlet = Inlet(component_system, name='inlet')
inlet.flow_rate = 6.683738370512285e-8

column = GeneralRateModel(component_system, name='column')
column.binding_model = binding_model

column.length = 0.014
column.diameter = 0.02
column.bed_porosity = 0.37
column.particle_radius = 4.5e-5
column.particle_porosity = 0.75
column.axial_dispersion = 5.75e-8
column.film_diffusion = column.n_comp * [6.9e-6]
column.pore_diffusion = [7e-10, 6.07e-11, 6.07e-11, 6.07e-11]
column.surface_diffusion = column.n_bound_states * [0.0]

column.c = [50, 0, 0, 0]
column.cp = [50, 0, 0, 0]
column.q = [binding_model.capacity, 0, 0, 0]

outlet = Outlet(component_system, name='outlet')

# Flow Sheet
flow_sheet = FlowSheet(component_system)

flow_sheet.add_unit(inlet)
flow_sheet.add_unit(column)
flow_sheet.add_unit(outlet, product_outlet=True)

flow_sheet.add_connection(inlet, column)
flow_sheet.add_connection(column, outlet)

# Process
process = Process(flow_sheet, 'lwe')
process.cycle_time = 2000.0

load_duration = 9
t_gradient_start = 90.0
gradient_duration = process.cycle_time - t_gradient_start

c_load = np.array([50.0, 1.0, 1.0, 1.0])
c_wash = np.array([50.0, 0.0, 0.0, 0.0])
c_elute = np.array([500.0, 0.0, 0.0, 0.0])
gradient_slope = (c_elute - c_wash) / gradient_duration
c_gradient_poly = np.array(list(zip(c_wash, gradient_slope)))

process.add_event('load', 'flow_sheet.inlet.c', c_load)
process.add_event('wash', 'flow_sheet.inlet.c', c_wash, load_duration)
process.add_event('grad_start', 'flow_sheet.inlet.c', c_gradient_poly, t_gradient_start)

process_simulator = Cadet()

simulation_results = process_simulator.simulate(process)

from CADETProcess.plotting import SecondaryAxis
sec = SecondaryAxis()
sec.components = ['Salt']
sec.y_label = '$c_{salt}$'

simulation_results.solution.column.outlet.plot(secondary_axis=sec)

Hope that already helps!

All the best,
Hannah