Hello!
I am working on a project involving a reaction model with the goal of estimating stoichiometric coefficients to fit experimental data of a chemical reaction. My primary objective is to adjust the reaction model’s parameters so that simulated results align closely with experimental observations.
The reaction I want to adjust is the following one:
glucose + glycerol + NH3 → product
Experimental data is available for the concentration of these components over time and I am using the MassActionLaw class. To estimate the stoichiometric coefficients I am formulating the problem as an optimization problem, but I am having trouble correctly implementing this. Is it possible to solve this kind of problem using CADET? So far, I have tried implementing the following code, but without success:
import pandas as pd
from CADETProcess.processModel import ComponentSystem, MassActionLaw, Cstr, FlowSheet, Process
from CADETProcess.simulator import Cadet
from CADETProcess.reference import ReferenceIO
from CADETProcess.comparison import Comparator
from CADETProcess.optimization import OptimizationProblem, U_NSGA3
data_path = "experimental_data.xlsx"
data = pd.read_excel(data_path, index_col=0)
component_system = ComponentSystem(["glucose", "glycerol", "NH3", "CDW"])
reaction_system = MassActionLaw(component_system)
reaction_system.add_reaction(
indices=[0, 1, 2, 3],
coefficients=[-1.0, -1.0, -1.0, 1.0],
k_fwd=1.0,
k_bwd=0.0
)
reactor = Cstr(component_system, "reactor")
reactor.bulk_reaction_model = reaction_system
reactor.V = 1.0
reactor.c = [1.0, 1.0, 1.0, 0.0]
flow_sheet = FlowSheet(component_system, "flow_sheet")
flow_sheet.add_unit(reactor)
process = Process(flow_sheet, "reaction_fermentation")
process.cycle_time = 180
reference = ReferenceIO("experimental data", data.index, data, component_system=component_system)
comparator = Comparator("fermentation_comparator")
comparator.add_reference(reference)
comparator.add_difference_metric("RMSE", reference, "reactor.outlet", components=["glucose", "glycerol", "NH3", "CDW"])
optimization_problem = OptimizationProblem("fermentation_optimization")
optimization_problem.add_evaluation_object(process)
optimization_problem.add_variable(
name="stoichiometric_coefficient",
parameter_path="flow_sheet.reactor.bulk_reaction_model.stoich",
indices=(0),
lb=-5.0,
ub=5.0
)
simulator = Cadet()
optimization_problem.add_evaluator(simulator)
optimization_problem.add_objective(
comparator,
n_objectives=comparator.n_metrics,
requires=[simulator]
)
optimizer = U_NSGA3()
optimizer.n_cores = 4
optimizer.pop_size = 32
optimizer.n_max_gen = 20
optimization_results = optimizer.optimize(optimization_problem)
print(optimization_results)
optimization_results.plot_convergence()
optimization_results.plot_objectives()
Thank you very much in advance.
Kind regards,
Ruoxian