Operability analysis of a multistage membrane separation process for direct air capture (m-DAC) using AVEVA Process Simulation
Author: Vitor Gama, West Virginia University (PhD Student)
To address the impacts of fossil fuel emissions on climate change, CO2 capture has been expanded from point-source capture to CO2 removal from the atmosphere. The figure shows the direct air capture process, which utilizes gas separation membranes for the CO2 removal.
Figure 1: m-DAC Process flow diagram.
Process Overview: Multistage Membrane-Based Direct Air Capture (DAC)
This process is designed for direct air capture (DAC) of CO2, using a multistage membrane separation approach to concentrate carbon dioxide from atmospheric levels (~420 ppm) to a low-purity product (~5% CO2 molar fraction). The system is engineered to handle approximately 1 megaton of air per year, aligning with urgent climate action goals.
The final CO2-enriched stream is suitable for applications that tolerate lower purity, such as:
- Algae cultivation
- Enhanced indoor farming and greenhouses
- Mineral carbonation processes
Key operations include vacuuming the permeate using vacuum pumps, compressors to restore pressure, and heat exchangers to maintain temperatures to acceptable ranges in order to avoid membrane degradation [8].
Step-by-step set up of Opyrability with AVEVA Process Simulation
Step 1: Necessary imports for connection with APS and for Operability computations:
APS connection import
import simcentralconnect #AVEVA PROCESS SIMULATION REQUIRED IMPORT TO ENABLE CONNECTION
This import is essential to enable communication with APS. Once you have installed and configured your APS, you should be able to find the Scripting Interface files. In it, a step-by-step README file guides the user through enabling the connection.
import numpy as np
from opyrability import AIS2AOS_map, multimodel_rep, OI_eval #Operability algorigthms import from Opyrability library
from scipy.io import savemat
# Instantiating the required interfaces for the scripting interface
sc = simcentralconnect.connect().Result
sm = sc.GetService("ISimulationManager")
vm = sc.GetService("IVariableManager")
snap = sc.GetService("ISnapshotManager")
# Example of how to set options. API logging is ON by default. Disabled by changing to 'false'
sc.SetOptions(repr({'Timeout': 500000, 'EnableApiLogging': 'false'}))
SimCentral.Client.Auto loaded from: C:\Program Files\SimSci\SimCentral\Scripting\DotNetFwk
Step 2: Calling the simulation file you want to work with:
simFile = "APS_mDAC"
simName = "APS_mDAC" #WARNING: Sometimes APS might rename your simulation as its opened so always make sure the name of the simulation you are working with aligns with the current opened simulation
nameSnap_FM = "steady" #Note: This is only required in case the user wants to set the simulation to a specific snapshot (Forward mapping case snapshot)
nameSnap_MR = "steady2" #Note: This is only required in case the user wants to set the simulation to a specific snapshot (Multimodel representation case snapshot)
Step 3: Function for double checking if simulation exists:
def open_simulation(simName):
opened = False
try:
opened = sm.OpenSimulation(simName).Result
except System.AggregateException as ex:
if not isinstance(ex.InnerException, System.InvalidOperationException) \
or "simulation doesn't exists" not in ex.InnerException.Message:
raise
return opened
open_simulation(simName)
True
Step 4: Process model function to communicate with APS and Opyrability:
def M(u):
y = np.zeros(2) #Prealocating outputs
# Membrane properties case - First membrane module study
# --------- Restarting simulation snapshot before changes -----------------------------
snap.RevertSnapshot(simName,nameSnap_FM)
#Parameters required for SetVariable method vm.SetVariableValue(<string> simulation name, <object> variable, <object> value, <object> unit, <object> apiOptions)(more on methods and interfaces is available in the AVEVA Scripting Interface documentation)
vm.SetVariableValue(simName, "MDAC1.QCO2", u[0], "", ).Result
vm.SetVariableValue(simName, "MDAC2.QCO2", u[1], "", ).Result
# --------- Checking solution status -----------------------------
print(f"\nCalling simulation with inputs: {u}")
try:
status = sm.GetSimulationStatus(simName).Result #Retrieving solution status of the simulation. Argument [2] holds the boolean value that informs if the solver was capable to solve (True) or not (False) the simulation.
print(f"Initial simulation status: {str(status[2])}")
except Exception as e:
print("Failed to get simulation status:", e)
if (status[2]):
flag_conv = True
else:
flag_conv= False
if flag_conv is True:
# ------------------ PRODUCTIVITY VARIABLES -----------------------------------------
Feed_flow = vm.GetVariableValue(simName, "Air_feed.F", "kmol/h").Result
Permeate = vm.GetVariableValue(simName, "Product.F", "kmol/h", ).Result
Purity = vm.GetVariableValue(simName, "Product.z[CO2]", "mol frac", ).Result
# ---------------- AOS VARIABLES --------------------------------------------------
# -------------------- Purity vs. Recovery case study ----------------------
y[0] = Purity*100
y[1] = 100*((Permeate*Purity) / (Feed_flow*0.000420))
else:
# --------- Restarting solver to try again -----------------------------
snap.RevertSnapshot(simName,nameSnap_FM)
# --------- Checking solution status again-----------------------------
status = sm.GetSimulationStatus(simName).Result
print(u[0], u[1],"failed")
if (status[2]):
flag_conv = True
else:
flag_conv= False
if flag_conv is True:
# ------------------- MEMBRANE PROPERTIES CASE -------------------------------
#First membrane module study
vm.SetVariableValue(simName, "MDAC1.QCO2", u[0], "", ).Result
vm.SetVariableValue(simName, "MDAC2.QCO2", u[1], "", ).Result
# ------------------ PRODUCTIVITY VARIABLES -----------------------------------------
Feed_flow = vm.GetVariableValue(simName, "Air_feed.F", "kmol/h").Result
Permeate = vm.GetVariableValue(simName, "Product.F", "kmol/h", ).Result
Purity = vm.GetVariableValue(simName, "Product.z[CO2]", "mol frac", ).Result
# ---------------- AOS VARIABLES --------------------------------------------------
# -------------------- Purity vs. Recovery case study ----------------------
y[0] = Purity*100
y[1] = 100*((Permeate*Purity) / (Feed_flow*0.000420))
else:
pass
return y #Returning outputs for the Operability study
Step 5: Defining Operability study
The current case study aims to analyze how the membrane’s CO2 permeance on both modules affect the overall capture of CO2 in terms of its purity and recovery.
Input (AIS) |
Output (AOS) |
---|---|
CO2 Permeance (Membrane module 1) [GPU] |
CO2 purity [mol%] |
CO2 Permeance (Membrane module 2) [GPU] |
CO2 recovery [%] |
#---------------------- OPERABILIY STUDY --------------------------------------------------
AIS_bounds = np.array([[3.35e-8, 6.7e-06],[3.35e-8, 6.7e-07]]) #AIS bounds definition for the 2 inputs x 2 outputs case study
AIS_resolution = [10,10] #AIS discretization definition for the 2 inputs x 2 outputs case study
AIS, AOS = AIS2AOS_map(M, AIS_bounds, AIS_resolution) #Forwad mapping call for the 2 inputs x 2 outputs case study
Calling simulation with inputs: [0. 0.]
Initial simulation status: True
Calling simulation with inputs: [3.35e-08, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [7.742222222222222e-07, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [1.5149444444444445e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [2.255666666666667e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [2.9963888888888892e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [3.7371111111111116e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [4.477833333333333e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [5.2185555555555555e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [5.959277777777778e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [6.7e-06, 3.35e-08]
Initial simulation status: True
Calling simulation with inputs: [3.35e-08, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [7.742222222222222e-07, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [1.5149444444444445e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [2.255666666666667e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [2.9963888888888892e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [3.7371111111111116e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [4.477833333333333e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [5.2185555555555555e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [5.959277777777778e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [6.7e-06, 1.0422222222222223e-07]
Initial simulation status: True
Calling simulation with inputs: [3.35e-08, 1.7494444444444446e-07]
Initial simulation status: False
3.35e-08 1.7494444444444446e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 1.7494444444444446e-07]
Initial simulation status: False
7.742222222222222e-07 1.7494444444444446e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 1.7494444444444446e-07]
Initial simulation status: False
1.5149444444444445e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 1.7494444444444446e-07]
Initial simulation status: False
2.255666666666667e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 1.7494444444444446e-07]
Initial simulation status: False
2.9963888888888892e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 1.7494444444444446e-07]
Initial simulation status: False
3.7371111111111116e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 1.7494444444444446e-07]
Initial simulation status: False
4.477833333333333e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 1.7494444444444446e-07]
Initial simulation status: False
5.2185555555555555e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 1.7494444444444446e-07]
Initial simulation status: False
5.959277777777778e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [6.7e-06, 1.7494444444444446e-07]
Initial simulation status: False
6.7e-06 1.7494444444444446e-07 failed
Calling simulation with inputs: [3.35e-08, 2.4566666666666674e-07]
Initial simulation status: False
3.35e-08 2.4566666666666674e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 2.4566666666666674e-07]
Initial simulation status: False
7.742222222222222e-07 2.4566666666666674e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 2.4566666666666674e-07]
Initial simulation status: False
1.5149444444444445e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 2.4566666666666674e-07]
Initial simulation status: False
2.255666666666667e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 2.4566666666666674e-07]
Initial simulation status: False
2.9963888888888892e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 2.4566666666666674e-07]
Initial simulation status: False
3.7371111111111116e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 2.4566666666666674e-07]
Initial simulation status: False
4.477833333333333e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 2.4566666666666674e-07]
Initial simulation status: False
5.2185555555555555e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 2.4566666666666674e-07]
Initial simulation status: False
5.959277777777778e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [6.7e-06, 2.4566666666666674e-07]
Initial simulation status: False
6.7e-06 2.4566666666666674e-07 failed
Calling simulation with inputs: [3.35e-08, 3.1638888888888895e-07]
Initial simulation status: False
3.35e-08 3.1638888888888895e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 3.1638888888888895e-07]
Initial simulation status: False
7.742222222222222e-07 3.1638888888888895e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 3.1638888888888895e-07]
Initial simulation status: False
1.5149444444444445e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 3.1638888888888895e-07]
Initial simulation status: False
2.255666666666667e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 3.1638888888888895e-07]
Initial simulation status: False
2.9963888888888892e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 3.1638888888888895e-07]
Initial simulation status: False
3.7371111111111116e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 3.1638888888888895e-07]
Initial simulation status: False
4.477833333333333e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 3.1638888888888895e-07]
Initial simulation status: False
5.2185555555555555e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 3.1638888888888895e-07]
Initial simulation status: False
5.959277777777778e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [6.7e-06, 3.1638888888888895e-07]
Initial simulation status: False
6.7e-06 3.1638888888888895e-07 failed
Calling simulation with inputs: [3.35e-08, 3.8711111111111117e-07]
Initial simulation status: False
3.35e-08 3.8711111111111117e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 3.8711111111111117e-07]
Initial simulation status: False
7.742222222222222e-07 3.8711111111111117e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 3.8711111111111117e-07]
Initial simulation status: False
1.5149444444444445e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 3.8711111111111117e-07]
Initial simulation status: False
2.255666666666667e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 3.8711111111111117e-07]
Initial simulation status: False
2.9963888888888892e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 3.8711111111111117e-07]
Initial simulation status: False
3.7371111111111116e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 3.8711111111111117e-07]
Initial simulation status: False
4.477833333333333e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 3.8711111111111117e-07]
Initial simulation status: False
5.2185555555555555e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 3.8711111111111117e-07]
Initial simulation status: False
5.959277777777778e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [6.7e-06, 3.8711111111111117e-07]
Initial simulation status: False
6.7e-06 3.8711111111111117e-07 failed
Calling simulation with inputs: [3.35e-08, 4.578333333333334e-07]
Initial simulation status: False
3.35e-08 4.578333333333334e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 4.578333333333334e-07]
Initial simulation status: False
7.742222222222222e-07 4.578333333333334e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 4.578333333333334e-07]
Initial simulation status: False
1.5149444444444445e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 4.578333333333334e-07]
Initial simulation status: False
2.255666666666667e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 4.578333333333334e-07]
Initial simulation status: False
2.9963888888888892e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 4.578333333333334e-07]
Initial simulation status: False
3.7371111111111116e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 4.578333333333334e-07]
Initial simulation status: False
4.477833333333333e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 4.578333333333334e-07]
Initial simulation status: False
5.2185555555555555e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 4.578333333333334e-07]
Initial simulation status: False
5.959277777777778e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [6.7e-06, 4.578333333333334e-07]
Initial simulation status: False
6.7e-06 4.578333333333334e-07 failed
Calling simulation with inputs: [3.35e-08, 5.285555555555556e-07]
Initial simulation status: False
3.35e-08 5.285555555555556e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 5.285555555555556e-07]
Initial simulation status: False
7.742222222222222e-07 5.285555555555556e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 5.285555555555556e-07]
Initial simulation status: False
1.5149444444444445e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 5.285555555555556e-07]
Initial simulation status: False
2.255666666666667e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 5.285555555555556e-07]
Initial simulation status: False
2.9963888888888892e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 5.285555555555556e-07]
Initial simulation status: False
3.7371111111111116e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 5.285555555555556e-07]
Initial simulation status: False
4.477833333333333e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 5.285555555555556e-07]
Initial simulation status: False
5.2185555555555555e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 5.285555555555556e-07]
Initial simulation status: False
5.959277777777778e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [6.7e-06, 5.285555555555556e-07]
Initial simulation status: False
6.7e-06 5.285555555555556e-07 failed
Calling simulation with inputs: [3.35e-08, 5.992777777777778e-07]
Initial simulation status: False
3.35e-08 5.992777777777778e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 5.992777777777778e-07]
Initial simulation status: False
7.742222222222222e-07 5.992777777777778e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 5.992777777777778e-07]
Initial simulation status: False
1.5149444444444445e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 5.992777777777778e-07]
Initial simulation status: False
2.255666666666667e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 5.992777777777778e-07]
Initial simulation status: False
2.9963888888888892e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 5.992777777777778e-07]
Initial simulation status: False
3.7371111111111116e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 5.992777777777778e-07]
Initial simulation status: False
4.477833333333333e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 5.992777777777778e-07]
Initial simulation status: False
5.2185555555555555e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 5.992777777777778e-07]
Initial simulation status: False
5.959277777777778e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [6.7e-06, 5.992777777777778e-07]
Initial simulation status: False
6.7e-06 5.992777777777778e-07 failed
Calling simulation with inputs: [3.35e-08, 6.7e-07]
Initial simulation status: False
3.35e-08 6.7e-07 failed
Calling simulation with inputs: [7.742222222222222e-07, 6.7e-07]
Initial simulation status: False
7.742222222222222e-07 6.7e-07 failed
Calling simulation with inputs: [1.5149444444444445e-06, 6.7e-07]
Initial simulation status: False
1.5149444444444445e-06 6.7e-07 failed
Calling simulation with inputs: [2.255666666666667e-06, 6.7e-07]
Initial simulation status: False
2.255666666666667e-06 6.7e-07 failed
Calling simulation with inputs: [2.9963888888888892e-06, 6.7e-07]
Initial simulation status: False
2.9963888888888892e-06 6.7e-07 failed
Calling simulation with inputs: [3.7371111111111116e-06, 6.7e-07]
Initial simulation status: False
3.7371111111111116e-06 6.7e-07 failed
Calling simulation with inputs: [4.477833333333333e-06, 6.7e-07]
Initial simulation status: False
4.477833333333333e-06 6.7e-07 failed
Calling simulation with inputs: [5.2185555555555555e-06, 6.7e-07]
Initial simulation status: False
5.2185555555555555e-06 6.7e-07 failed
Calling simulation with inputs: [5.959277777777778e-06, 6.7e-07]
Initial simulation status: False
5.959277777777778e-06 6.7e-07 failed
Calling simulation with inputs: [6.7e-06, 6.7e-07]
Initial simulation status: False
6.7e-06 6.7e-07 failed

The AIS axes represent the CO2 permeance of each membrane module (u1 = membrane module 1 and u2 = membrane module 2).
The AOS axes show the outputs of the simulation (y1 = CO2 purity in mol% and y2 = CO2 recovery in %). The color gradient maps input cases to their respective outputs, and a proportional relationship can be observed between CO2 purity and recovery as the membrane properties vary. This showcases Opyrability’s capability to assess process outcomes via the manipulation of input variables.
Multimodel representation
This section covers the application of another feature of the Opyrability package, the multimodel representation. With it, it is possible to generate an AOS visualization using paired polytopes, which could assist in effective OI calculations.
Process model function for Multimodel case:
def Multi(u):
y = np.zeros(2) #Prealocating outputs
# Membrane properties case - First membrane module study
# --------- Restarting simulation snapshot before changes -----------------------------
snap.RevertSnapshot(simName,nameSnap_MR)
#Parameters required for SetVariable method vm.SetVariableValue(<string> simulation name, <object> variable, <object> value, <object> unit, <object> apiOptions)(more on methods and interfaces is available in the AVEVA Scripting Interface documentation)
vm.SetVariableValue(simName, "MDAC1.Nt", u[0], "", ).Result
vm.SetVariableValue(simName, "MDAC2.Nt", u[1], "", ).Result
# --------- Checking solution status -----------------------------
print(f"\nCalling simulation with inputs: {u}")
try:
status = sm.GetSimulationStatus(simName).Result #Retrieving solution status of the simulation. Argument [2] holds the boolean value that informs if the solver was capable to solve (True) or not (False) the simulation.
print(f"Initial simulation status: {str(status[2])}")
except Exception as e:
print("Failed to get simulation status:", e)
if (status[2]):
flag_conv = True
else:
flag_conv= False
if flag_conv is True:
# ------------------ PRODUCTIVITY VARIABLES -----------------------------------------
Feed_flow = vm.GetVariableValue(simName, "Air_feed.F", "kmol/h").Result
Permeate = vm.GetVariableValue(simName, "Product.F", "kmol/h", ).Result
Purity = vm.GetVariableValue(simName, "Product.z[CO2]", "mol frac", ).Result
# ---------------- AOS VARIABLES --------------------------------------------------
# -------------------- Purity vs. Recovery case study ----------------------
y[0] = Purity*100
y[1] = 100*((Permeate*Purity) / (Feed_flow*0.000420))
else:
# --------- Restarting solver to try again -----------------------------
snap.RevertSnapshot(simName,nameSnap_MR)
# --------- Checking solution status again-----------------------------
status = sm.GetSimulationStatus(simName).Result
print(u[0], u[1],"failed")
if (status[2]):
flag_conv = True
else:
flag_conv= False
if flag_conv is True:
# ------------------- MEMBRANE PROPERTIES CASE -------------------------------
#First membrane module study
vm.SetVariableValue(simName, "MDAC1.Nt", u[0], "", ).Result
vm.SetVariableValue(simName, "MDAC2.Nt", u[1], "", ).Result
# ------------------ PRODUCTIVITY VARIABLES -----------------------------------------
Feed_flow = vm.GetVariableValue(simName, "Air_feed.F", "kmol/h").Result
Permeate = vm.GetVariableValue(simName, "Product.F", "kmol/h", ).Result
Purity = vm.GetVariableValue(simName, "Product.z[CO2]", "mol frac", ).Result
# ---------------- AOS VARIABLES --------------------------------------------------
# -------------------- Purity vs. Recovery case study ----------------------
y[0] = Purity*100
y[1] = 100*((Permeate*Purity) / (Feed_flow*0.000420))
else:
pass
return y #Returning outputs for the Operability study
Defining Operability study used for multimodel representation
The current case study analyzes how the available membrane surface area (manipulated through the module’s number of fibers) affects the overall capture of CO2 in terms of CO2 purity and recovery.
Input (AIS) |
Output (AOS) |
---|---|
Membrane module 1 number of fibers |
CO2 purity [mol%] |
Membrane module 2 number of fibers |
CO2 recovery [%] |
#---------------------- MULTIMODEL REPRESENTATION STUDY --------------------------------------------------
AIS_bounds = np.array([[8e5, 1.3e6],[1.5e5, 3.5e5]]) #AIS bounds definition for the 2 inputs x 2 outputs case study
AIS_resolution = [5,5] #AIS discretization definition
AOS_reg = multimodel_rep(Multi, AIS_bounds, AIS_resolution) #Multimodel representation call
Calling simulation with inputs: [800000. 150000.]
Initial simulation status: True
Calling simulation with inputs: [800000.0, 150000.0]
Initial simulation status: True
Calling simulation with inputs: [925000.0, 150000.0]
Initial simulation status: True
Calling simulation with inputs: [1050000.0, 150000.0]
Initial simulation status: True
Calling simulation with inputs: [1175000.0, 150000.0]
Initial simulation status: True
Calling simulation with inputs: [1300000.0, 150000.0]
Initial simulation status: True
Calling simulation with inputs: [800000.0, 200000.0]
Initial simulation status: True
Calling simulation with inputs: [925000.0, 200000.0]
Initial simulation status: True
Calling simulation with inputs: [1050000.0, 200000.0]
Initial simulation status: True
Calling simulation with inputs: [1175000.0, 200000.0]
Initial simulation status: True
Calling simulation with inputs: [1300000.0, 200000.0]
Initial simulation status: True
Calling simulation with inputs: [800000.0, 250000.0]
Initial simulation status: True
Calling simulation with inputs: [925000.0, 250000.0]
Initial simulation status: True
Calling simulation with inputs: [1050000.0, 250000.0]
Initial simulation status: True
Calling simulation with inputs: [1175000.0, 250000.0]
Initial simulation status: True
Calling simulation with inputs: [1300000.0, 250000.0]
Initial simulation status: True
Calling simulation with inputs: [800000.0, 300000.0]
Initial simulation status: True
Calling simulation with inputs: [925000.0, 300000.0]
Initial simulation status: True
Calling simulation with inputs: [1050000.0, 300000.0]
Initial simulation status: True
Calling simulation with inputs: [1175000.0, 300000.0]
Initial simulation status: True
Calling simulation with inputs: [1300000.0, 300000.0]
Initial simulation status: True
Calling simulation with inputs: [800000.0, 350000.0]
Initial simulation status: True
Calling simulation with inputs: [925000.0, 350000.0]
Initial simulation status: True
Calling simulation with inputs: [1050000.0, 350000.0]
Initial simulation status: True
Calling simulation with inputs: [1175000.0, 350000.0]
Initial simulation status: True
Calling simulation with inputs: [1300000.0, 350000.0]
Initial simulation status: True

Based on the region generated, the OI evaluation will provide a perspective on process’ operability within the DOS outlined for this case.
Desired Output Set (DOS) |
|
---|---|
CO2 purity [mol%] (y1) |
3 - 7 |
CO2 recovery [%] (y2) |
11 - 15 |
OI evaluation
DOS_bounds = np.array([[3, 7],
[11, 15]])
OI = OI_eval(AOS_reg, DOS_bounds)

The OI calculation shows that within the DOS the process is 70.61% operable.