<jupyter_start><jupyter_text>Introduction Extractive distillation of MethylCyloHexane/Toluene using Phenol adapted from [Tiverios and <NAME> in Ind.Eng.Chem.Res. (2000) 39, pp. 1614-1623](http://pubs.acs.org/doi/pdf/10.1021/ie990654k)[Link to flowsheet on ChemSep homepage](http://www.chemsep.org/downloads/data/CScasebook_MCHT.png)  .NET Initialization<jupyter_code>import clr
clr.AddReference(r"..\bin\MiniSim.Core")

import MiniSim.Core.Expressions as expr
from  MiniSim.Core.Flowsheeting import MaterialStream, Flowsheet
import MiniSim.Core.Numerics as num
from MiniSim.Core.UnitsOfMeasure import Unit, SI, METRIC, PhysicalDimension
from MiniSim.Core.ModelLibrary import Flash, Heater, Mixer, Splitter, EquilibriumStageSection
import MiniSim.Core.PropertyDatabase as chemsep
from MiniSim.Core.Reporting import Generator, StringBuilderLogger
from MiniSim.Core.Thermodynamics import ThermodynamicSystem
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = (16,8)
plt.rcParams['grid.color'] = 'k'<jupyter_output><empty_output><jupyter_text>General Objects Instantiation<jupyter_code>Database = chemsep.ChemSepAdapter()
logger = StringBuilderLogger();
reporter = Generator(logger)
def calc(flowsheet, relax, maxIter):
    presolver=  num.BasicNewtonSolver(logger)
    presolver.MaximumIterations=maxIter
    presolver.BrakeFactor=relax
    presolver.Solve(flowsheet)
    print (logger.Flush())
    
def decomp(flowsheet):
    solver= num.DecompositionSolver(logger)
    solver.Solve(flowsheet)
    print (logger.Flush())
    
def thermoAnalysis(psys):
    numComps=len(sys.Components)
    names=sys.GetComponentIds()

    numSteps=20    
    mixture= MaterialStream("Mix", sys)
    mixture.Specify("VF",0.0)
    mixture.Specify("P",psys, METRIC.mbar)
    for c in names:
        mixture.Specify("n["+c+"]",1.0)
    mixture.InitializeFromMolarFlows()
    mixture.FlashPZ()

    test= Flowsheet("test")
    test.AddMaterialStream(mixture)

    solver= num.DecompositionSolver(logger)
    result=solver.Solve(test)

    fig,axs=plt.subplots(numComps,numComps,figsize=(8,8))
    for i in range(numComps):
        for j in range(numComps):       
            if j!=i:
                xvec=[]
                yvec=[]
                for c in range(numSteps):
                    for k in range(numComps):                    
                        mixture.Specify("n["+names[k]+"]",0.0)
                    mixture.Specify("n["+names[i]+"]",c/(numSteps-1))
                    mixture.Specify("n["+names[j]+"]",1.0-c/(numSteps-1))
                    mixture.InitializeFromMolarFlows()
                    mixture.FlashPZ()
                    solver.Solve(test)                               
                    xvec.append(mixture.GetVariable('xL['+names[j]+']').Val())               
                    yvec.append(mixture.GetVariable('xV['+names[j]+']').Val())               
                axs[i,j].plot(xvec, yvec)
                axs[i,j].plot(xvec, xvec)              
                axs[i,j].set_title(names[j] +' in '+names[i])
                axs[i,j].set_xlabel('$x_{'+names[j]+'}$')       
                axs[i,j].set_ylabel('$y_{'+names[j]+'}$')
                axs[i, j].set_aspect('equal', 'box')
            else:
                axs[i, j].axis('off')        

    plt.tight_layout()
    logger.Flush()
    plt.suptitle('(x,y)-Diagram at '+str(round(psys,2))+' mbar', y=1.05);<jupyter_output><empty_output><jupyter_text>Set up Thermodynamics<jupyter_code>sys= ThermodynamicSystem("Test2","NRTL", "default")

sys.AddComponent(Database.FindComponent("Methylcyclohexane").RenameID("MCH"))
sys.AddComponent(Database.FindComponent("Toluene").RenameID("TOLUOL"))
sys.AddComponent(Database.FindComponent("Phenol").RenameID("PHENOL"))
Database.FillBIPs(sys)
NRTL = sys.GetBinaryParameters("NRTL")
NRTL.SetParam("B",sys.Components[0], sys.Components[1],-43.2404 )
NRTL.SetParam("B",sys.Components[1], sys.Components[0],134.062 )
NRTL.SetParamSymmetric("C",sys.Components[0], sys.Components[1],0.3 )

kmolh=Unit.Make([SI.kmol],[SI.h])
tonh=Unit.Make([METRIC.ton],[SI.h])

sys.VariableFactory.SetOutputDimension(PhysicalDimension.HeatFlow, SI.MW)
sys.VariableFactory.SetOutputDimension(PhysicalDimension.Pressure, METRIC.bar)
sys.VariableFactory.SetOutputDimension(PhysicalDimension.MassFlow, tonh)
thermoAnalysis(1000)<jupyter_output><empty_output><jupyter_text>Azeotropic column<jupyter_code>Feed = (MaterialStream("Feed", sys)
        .Specify("T",25, METRIC.C)
        .Specify("P",1, METRIC.bar)
        .Specify("n[MCH]",90, kmolh)
        .Specify("n[TOLUOL]", 90, kmolh)
        .Specify("n[PHENOL]", 0, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

Recycle = (MaterialStream("Recycle", sys)
        .Specify("T",151, METRIC.C)
        .Specify("P",1, METRIC.bar)
        .Specify("n[MCH]",0, kmolh)
        .Specify("n[TOLUOL]", 0.1, kmolh)
        .Specify("n[PHENOL]", 250, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

S01 = MaterialStream("S01", sys)
S02 = MaterialStream("S02", sys)
S03 = (MaterialStream("S03", sys)
        .Init("T", 101, METRIC.C)
        .Init("P", 1, METRIC.bar)
        .Init("n[MCH]",719, kmolh)
        .Init("n[TOLUOL]", 6, kmolh)
        .Init("n[PHENOL]", 0.1, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

S04 = MaterialStream("S04", sys)
S05 = (MaterialStream("S05", sys)
        .Init("T", 150, METRIC.C)
        .Init("P", 1, METRIC.bar)
        .Init("n[MCH]",0, kmolh)
        .Init("n[TOLUOL]", 450, kmolh)
        .Init("n[PHENOL]", 179, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

MCH = MaterialStream("MCH", sys)
B1 = MaterialStream("B1", sys)

C1 = (EquilibriumStageSection("C1",sys,39)
        .Connect("VIn", S05)
        .Connect("LIn", S03)
        .Connect("VOut", S01)
        .Connect("LOut", S04)
        .ConnectFeed(Feed,25)
        .ConnectFeed(Recycle,10)
        .MakeAdiabatic()
        .MakeIsobaric()
        .FixStageEfficiency(1.0)
        .Initialize(4.7,0.7,logger))

REB1 = (Flash("REB1",sys)
        .Connect("In", S04)
        .Connect("Vap", S05)
        .Connect("Liq", B1)
        .Specify("P", 1, METRIC.bar)
        .Specify("VF",0.65)
        .Initialize())

COND1 = (Heater("COND1",sys)
        .Connect("In", S01)
        .Connect("Out", S02)
        .Specify("P",1, METRIC.bar)
        .Specify("VF",0)\
        .Initialize())

RefluxRatio1=4.7
REFSPL1 = (Splitter("REFSPL1",sys)\
        .Connect("In", S02)\
        .Connect("Out1", MCH)\
        .Connect("Out2", S03)\
        .Specify("DP",0, METRIC.bar)\
        .Specify("K",1-RefluxRatio1/(1.0+RefluxRatio1))\
        .Initialize())

flowsheet= (Flowsheet("Flow")
        .AddMaterialStreams(Feed, Recycle, S01,S02,S03,B1,S04,S05, MCH)
        .AddUnits(C1, REB1, COND1, REFSPL1))
decomp(flowsheet)
decomp(flowsheet)
reporter.Report(flowsheet,5,False)
print(logger.Flush())<jupyter_output>Report for flowsheet Flow
================================================

Material Streams

System                    Test2      

Property                  Unit               Feed      Recycle          S01          S02          S03

Temperature               °C              25.0000     151.0000     101.6468     101.4339     101.4339
Pressure                  bar              1.0000       1.0000       1.0000       1.0000       1.0000
Vapor Fraction            mol/mol          0.0000       0.0000       1.0000       0.0000       0.0000
Specific Enthalpy         kJ/kmol     -36880.0451  -32748.4198   11111.8634  -20705.0402  -20705.0402
Phase                                      Liquid       Liquid  LiquidVapor  BubblePoint       Liquid

Total Molar Flow          kmol/h         180.0000     250.1000     690.8486     690.8486     569.6471
                      MCH kmol/h          90.0000       0.0000     512.9497     512.9497     422.9586
                   TOLUOL kmol[...]<jupyter_text>Stripping column<jupyter_code>S06 = MaterialStream("S06", sys)
S07 = MaterialStream("S07", sys)
S08 = (MaterialStream("S08", sys)
        .Init("T", 110, METRIC.C)
        .Init("P", 1, METRIC.bar)
        .Init("n[MCH]",1, kmolh)
        .Init("n[TOLUOL]", 400, kmolh)
        .Init("n[PHENOL]", 10, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

S09 = MaterialStream("S09", sys)

S10 = (MaterialStream("S10", sys)
        .Init("T", 180, METRIC.C)
        .Init("P", 1, METRIC.bar)
        .Init("n[MCH]",1, kmolh)
        .Init("n[TOLUOL]", 1, kmolh)
        .Init("n[PHENOL]", 300, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

Toluol = MaterialStream("Toluol", sys)
B2 = MaterialStream("B2", sys)

C2 = (EquilibriumStageSection("C2",sys,19)
        .Connect("VIn", S10)
        .Connect("LIn", S08)
        .Connect("VOut", S06)
        .Connect("LOut", S09)
        .ConnectFeed(B1,12)
        .MakeAdiabatic()
        .MakeIsobaric()
        .FixStageEfficiency(1.0)
        .Initialize(2.9,0.2,logger))

REB2 = (Flash("REB2",sys)
        .Connect("In", S09)
        .Connect("Vap", S10)
        .Connect("Liq", B2)
        .Specify("P",1, METRIC.bar)
        .Specify("VF",0.4)
        .Initialize())

COND2 = (Heater("COND2",sys)
    .Connect("In", S06)
    .Connect("Out", S07)
    .Specify("P",1, METRIC.bar)
    .Specify("VF",0)
    .Initialize())

RefluxRatio2=2.9
REFSPL2 = (Splitter("REFSPL2",sys)
    .Connect("In", S07)
    .Connect("Out1", Toluol)
    .Connect("Out2", S08)
    .Specify("DP",0, METRIC.bar)
    .Specify("K",0.47)
    .Initialize())

C2.Initialize(1.9,0.2,logger)
REB2.Solve()
COND2.Solve()
REFSPL2.Solve()
logger.Flush()

flowsheet.AddMaterialStreams(S06,S07,S08,B2,S09,S10,Toluol).AddUnits(C2, REB2, COND2, REFSPL2);
decomp(flowsheet)<jupyter_output>Decomposition Result: V=1279, E=1279, Blocks=313, Singletons=299
Block Statistics:
   # Var # Blocks % Blocks
       1      299  95,53 %
       7        6   1,92 %
       8        6   1,92 %
     315        1   0,32 %
     575        1   0,32 %
Problem NLAES was successfully solved (0,37 seconds)<jupyter_text>Reach Design Specifications: Purities<jupyter_code>REB1.Unspecify("VF")
MCH.GetVariable("x[MCH]").Fix(0.99)

decomp(flowsheet)
REB2.Unspecify("VF")
Toluol.GetVariable("x[TOLUOL]").Fix(0.99)

decomp(flowsheet)<jupyter_output>Decomposition Result: V=1279, E=1279, Blocks=303, Singletons=289
Block Statistics:
   # Var # Blocks % Blocks
       1      289  95,38 %
       7        6   1,98 %
       8        6   1,98 %
     320        1   0,33 %
     580        1   0,33 %
Problem NLAES was successfully solved (0,12 seconds)<jupyter_text>Close Recycle loop<jupyter_code>Recycle.Unfix()
Makeup = (MaterialStream("Makeup", sys)
        .Specify("T",104, METRIC.C)
        .Specify("P",1, METRIC.bar)
        .Specify("n[MCH]",0, kmolh)
        .Specify("n[TOLUOL]", 0, kmolh)
        .Init("n[PHENOL]", 0.03, kmolh)
        .InitializeFromMolarFlows()
        .FlashPT())

MIX01 = (Mixer("MIX01",sys)
    .Connect("In", B2)
    .Connect("In", Makeup)
    .Connect("Out", Recycle)
    .Specify("P",1, METRIC.bar)
    .Initialize())

flowsheet.AddMaterialStream(Makeup).AddUnit(MIX01)
Recycle.GetVariable("n").Fix(251/3.6)
calc(flowsheet,1.00,5)
decomp(flowsheet)<jupyter_output>Iter Step Length     Infeasibility   Damping Notes
0    0               146,294         1       
1    483172          50,0161         1       
2    1490,85         0,241661        1       
3    877,874         0,000393082     1       
4    877,501         0,00115928      0,9989994327374 
5    0,304437        3,45382E-06     1       
Maximum number of iterations exceeded!

Decomposition Result: V=1305, E=1305, Blocks=284, Singletons=273
Block Statistics:
   # Var # Blocks % Blocks
       1      273  96,13 %
       7        3   1,06 %
       8        7   2,46 %
     955        1   0,35 %
Problem NLAES was successfully solved (1,49 seconds)<jupyter_text>Print Results<jupyter_code>reporter.Report(flowsheet,5,False)
print(logger.Flush())<jupyter_output>Report for flowsheet Flow
================================================

Material Streams

System                    Test2      

Property                  Unit               Feed      Recycle          S01          S02          S03

Temperature               °C              25.0000     180.4322     100.4254     100.4183     100.4183
Pressure                  bar              1.0000       1.0000       1.0000       1.0000       1.0000
Vapor Fraction            mol/mol          0.0000       0.0000       1.0000       0.0000       0.0000
Specific Enthalpy         kJ/kmol     -36880.0451  -25842.8178   11590.0216  -19609.6324  -19609.6324
Phase                                      Liquid       Liquid        Vapor  BubblePoint       Liquid

Total Molar Flow          kmol/h         180.0000     251.0000     517.6848     517.6848     426.8629
                      MCH kmol/h          90.0000       0.0000     512.5079     512.5079     422.5943
                   TOLUOL kmol[...]<jupyter_text>Column Profiles Azeotropic Column<jupyter_code>x={}
x["MCH"]=C1.GetProfile("x","MCH")
x["TOLUOL"]=C1.GetProfile("x","TOLUOL")
x["PHENOL"]=C1.GetProfile("x","PHENOL")

stages= range(1, C1.NumberOfTrays+1)
df_comp= pd.DataFrame(zip(x["MCH"],x["TOLUOL"],x["PHENOL"] ), 
                      index=stages, 
                      columns=sys.GetComponentIds())

plt.plot( df_comp["MCH"], stages, linestyle='-', marker='o')
plt.plot( df_comp["TOLUOL"], stages, linestyle='-', marker='o')
plt.plot( df_comp["PHENOL"], stages, linestyle='-', marker='o')
plt.gca().invert_yaxis()
plt.legend(sys.GetComponentIds())
plt.xlabel("Molar Composition [-]")
plt.ylabel("Stage")
plt.title("Liquid Composition Profile C1");
x={}
x["MCH"]=C2.GetProfile("x","MCH")
x["TOLUOL"]=C2.GetProfile("x","TOLUOL")
x["PHENOL"]=C2.GetProfile("x","PHENOL")

stages= range(1, C2.NumberOfTrays+1)
df_comp= pd.DataFrame(zip(x["MCH"],x["TOLUOL"],x["PHENOL"] ), 
                      index=stages, 
                      columns=sys.GetComponentIds())

plt.plot( df_comp["MCH"], stages, linestyle='-', marker='o')
plt.plot( df_comp["TOLUOL"], stages, linestyle='-', marker='o')
plt.plot( df_comp["PHENOL"], stages, linestyle='-', marker='o')
plt.gca().invert_yaxis()
plt.legend(sys.GetComponentIds())
plt.xlabel("Molar Composition [-]")
plt.ylabel("Stage")
plt.title("Liquid Composition Profile C2");<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15723357261181667, 'fraction_numerical': 0.07061016013252347, 'mean_word_length': 2.4829326923076924, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '588969', 'license': 'MIT', 'n_tokens_mistral': 5914, 'n_tokens_neox': 5240, 'n_words': 857, 'path': 'doc/AzeotropicDistillation.ipynb', 'repo_name': 'Nukleon84/MiniSim', 'size': '14491'}