BioSTEAMDevelopmentGroup / Bioindustrial-Park

BioSTEAM's Premier Repository for Biorefinery Models and Results
MIT License
38 stars 18 forks source link

Requests for error that cannot solve for pressure yet #61

Closed zasddsgg closed 1 year ago

zasddsgg commented 1 year ago

Hello, when I called class PretreatmentReactorSystem, I changed self.reactions.adiabatic_reaction(liquid) in the code to self.reactions(liquid) (https://github.com/BioSTEAMDevelopmentGroup/Bioindustrial-Park/blob/master/biorefineries/cellulosic/units.py). At the same time, I added V=0 in def init(self, ID='', ins=None, outs=(), T=130+273.15, V=0, thermos=None, tau=0.166, V_wf=0.8, length_to_diameter=2, vessel_material='Stainless steel 316', vessel_type='Horizontal',reactions=None, run_vle=True) and added self.V = V after self.T = T.

Because I want the gas fraction of the outlet stream to be zero, and I don't want the reaction to be adiabatic (I want to look at the heat duty of the pretreatment reaction). But when I do that, an error (NotImplementedError: cannot solve for pressure yet) was reported. I analyzed the reason, it’s because that dH_bubble = (H - H_bubble) if dH_bubble <= 0: raise NotImplementedError('cannot solve for pressure yet') was set in the VLE source code (https://biosteam.readthedocs.io/en/latest/_modules/thermosteam/equilibrium/vle.html#).

Does that mean that when having an exothermic reaction, an error that cannot solve for pressure yet was reported? Because I want to see the heat duty of the actual pretreatment (not necessarily 0), I don't want to set the reaction under adiabatic condition. But if I don't set the adiabatic, the above error will be reported. May I ask if you have any solution for that. Thank you very much. Wish you a good day.

yoelcortes commented 1 year ago

Hi @zasddsgg,

~setting V and T is not implemented in thermosteam yet. I will add it sometime this weekend. In the mean time that this gets added, you can use V=0 and P=some value (replace T for P). V is the vapor fraction and setting V=0 sets the mixture to the bubble point. I will leave this issue open until I add the feature.~

It looks like you are setting H and T, not V and T. You should be able to set V and T without issues. If you have any issues, please send me the full traceback (error log) and the code you are using.

Thanks!

zasddsgg commented 1 year ago

Thank you for your help, but in class pretreatment system,adiabatic reactions needed to be set ,or the above error will be reported. If I don't want to set adiabatic conditions,what should I do for solving that error. Thank you a lot for your help.


From: Yoel @.> Sent: Wednesday, February 22, 2023 10:50:02 PM To: BioSTEAMDevelopmentGroup/Bioindustrial-Park @.> Cc: Dexin ZHANG 张德鑫 @.>; Mention @.> Subject: Re: [BioSTEAMDevelopmentGroup/Bioindustrial-Park] Requests for error that cannot solve for pressure yet (Issue #61)

Hi @zasddsgghttps://apc01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fzasddsgg&data=05%7C01%7Czhangdexin%40westlake.edu.cn%7Cb4adaba8f62844711eac08db14e416fc%7C7e82de2f7ef644169b9644c1457be81b%7C1%7C0%7C638126742089913039%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=GWC47i9AfT0X2IT1mPaDfYK7fYKbSWF4gSSPUtJPoUo%3D&reserved=0, setting V and T is not implemented in thermosteam yet. I will add it sometime this weekend. In the mean time that this gets added, you can use V=0 and P=some value (replace T for P). V is the vapor fraction and setting V=0 sets the mixture to the bubble point. I will leave this issue open until I add the feature.

Thanks!

― Reply to this email directly, view it on GitHubhttps://apc01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FBioSTEAMDevelopmentGroup%2FBioindustrial-Park%2Fissues%2F61%23issuecomment-1440174598&data=05%7C01%7Czhangdexin%40westlake.edu.cn%7Cb4adaba8f62844711eac08db14e416fc%7C7e82de2f7ef644169b9644c1457be81b%7C1%7C0%7C638126742089913039%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=zqukwrMk04OKdI9HE5aHsaRe5rcP7MMWNZABGenVdXc%3D&reserved=0, or unsubscribehttps://apc01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FA57G2RPYZZ7QZCVBQCJ3LHLWYYRRVANCNFSM6AAAAAAVELNHXA&data=05%7C01%7Czhangdexin%40westlake.edu.cn%7Cb4adaba8f62844711eac08db14e416fc%7C7e82de2f7ef644169b9644c1457be81b%7C1%7C0%7C638126742089913039%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=u5Pv5tZhDoOAhgTTzl5K4JMyfneiGLuMPsLonq1SVXw%3D&reserved=0. You are receiving this because you were mentioned.Message ID: @.***>

yoelcortes commented 1 year ago

I would suggest you subclass the PretreatmentReactorSystem class and define a new _run method that does what you would like. Another option is to create a specification that overrides the _run method (https://biosteam.readthedocs.io/en/latest/tutorial/Process_specifications.html).

yoelcortes commented 1 year ago

@zasddsgg, I updated my reply regarding setting V and T above.

zasddsgg commented 1 year ago

Thank you for your help and suggestions. Compared to the original code, I changed T and V, as well as some conversion rates, and changed self.reactions.adiabatic_reaction(liquid) to self.reactions(liquid). My source code and error information are as follows:

import biosteam as bst bst.nbtutorial() from biosteam.units.decorators import cost from biosteam import Unit from biosteam import units from biosteam.units.design_tools.geometry import cylinder_diameter_from_volume

from thermosteam import MultiStream import thermosteam as tmo

from biorefineries import cellulosic cs = cellulosic.Biorefinery('corn stover ethanol') chemicals_cs = cs.chemicals bst.settings.set_thermo(chemicals_cs) bst.main_flowsheet.set_flowsheet('corn stover_ethanol')

cornstover = bst.Stream( 'cornstover', Glucan=0.28, Xylan=0.1562, Galactan=0.001144, Arabinan=0.01904, Mannan=0.0048, Lignin=0.12608, Acetate=0.01448, Protein=0.0248, Extract=0.1172, Ash=0.03944, Sucrose=0.00616, Water=0.2, total_flow=104229.16, units='kg/hr', price=0.05158816935126135, ) sulfuric_acid = bst.Stream( 'sulfuric_acid', P=5.4*101325, T=294.15, Water=130, H2SO4=1800, units='kg/hr', price=0.0897171175961359 )

U101 = cellulosic.units.FeedStockHandling('U101', Cornstover)

@cost('Dry flow rate', 'Pretreatment reactor system', units='kg/hr', S=83333, CE=522, cost=19812400 * 0.993, n=0.6, kW=4578, BM=1.5) class PretreatmentReactorSystem(bst.units.design_tools.PressureVessel, Unit): _N_ins = 1 _N_outs = 2 _graphics = bst.Flash._graphics _units = {'Residence time': 'hr', 'Reactor volume': 'm3'}

def __init__(self, ID='', ins=None, outs=(), T=110+273.15, V=0, thermo=None, 
             tau=0.166, V_wf=0.8, length_to_diameter=2, 
             vessel_material='Stainless steel 316', 
             vessel_type='Horizontal',
             reactions=None,
             run_vle=True):
    Unit.__init__(self, ID, ins, outs, thermo)
    self._load_components()
    vapor, liquid = self.outs
    vapor.phase = 'g'
    self.T = T
    self.V = V
    chemicals = self.chemicals
    if reactions is None:
        self.reactions = ParallelRxn([
    #            Reaction definition                 Reactant    Conversion
    Rxn('Glucan + H2O -> Glucose',                   'Glucan',   0.0990),
    Rxn('Glucan -> HMF + 2 H2O',                     'Glucan',   0.0030),
    Rxn('Galactan + H2O -> Galactose',               'Galactan', 0.9000),
    Rxn('Galactan -> HMF + 2 H2O',                   'Galactan', 0.0500),
    Rxn('Mannan + H2O -> MannoseOligomer',           'Mannan',   0.0240),
    Rxn('Mannan -> HMF + 2 H2O',                     'Mannan',   0.0500),
    Rxn('Mannan + H2O -> Mannose',                   'Mannan',   0.9000),
    Rxn('Sucrose -> HMF + Glucose + 2H2O',           'Sucrose',  1.0000),
    Rxn('Xylan + H2O -> Xylose',                     'Xylan',    0.9000),
    Rxn('Xylan + H2O -> XyloseOligomer',             'Xylan',    0.0240),
    Rxn('Xylan -> Furfural + 2 H2O',                 'Xylan',    0.0500),
    Rxn('Arabinan + H2O -> Arabinose',               'Arabinan', 0.9000),
    Rxn('Arabinan + H2O -> ArabinoseOligomer',       'Arabinan', 0.0240),
    Rxn('Arabinan -> Furfural + 2 H2O',              'Arabinan', 0.050),
    Rxn('Acetate -> AceticAcid',                     'Acetate',  1.0000),
    Rxn('Furfural + 3 H2O -> Tar',                   'Furfural', 1.0000),        
    Rxn('HMF + 3 H2O -> 1.2 Tar',                    'HMF',      1.0000),
    Rxn('Lignin -> SolubleLignin',                   'Lignin',   0.0500)
        ])
        self.glucan_to_glucose = self.reactions[0]
        self.xylan_to_xylose = self.reactions[8]
        self.glucose_to_byproducts = self.reactions[1:3]
        self.xylose_to_byproducts = self.reactions[9:12]
    else:
        self.reactions = reactions
    self.tau = tau
    self.V_wf = V_wf
    self.length_to_diameter = length_to_diameter
    self.vessel_material = vessel_material
    self.vessel_type = vessel_type
    self.run_vle = run_vle

def _load_components(self):
    thermo = self.thermo
    self._multistream = MultiStream(None, thermo=thermo)

def _run(self):
    feed = self.ins[0]
    vapor, liquid = self.outs
    liquid.copy_like(feed)
    self.reactions(liquid)
    if self.T:
        if self.run_vle:
            ms = self._multistream
            ms.copy_like(liquid)
            ms.vle(T=self.T, H=ms.H)
            vapor.mol[:] = ms.imol['g']
            liquid.mol[:] = ms.imol['l']
            vapor.T = liquid.T = ms.T
            vapor.P = liquid.P = ms.P
        else:
            liquid.T = self.T

def _design(self):
    Design = self.design_results
    ins_F_vol = self.F_vol_in
    V_reactor = ins_F_vol * self.tau / self.V_wf
    P = self.outs[0].P * 0.000145038 # Pa to psi
    length_to_diameter = self.length_to_diameter
    D = cylinder_diameter_from_volume(V_reactor, self.length_to_diameter)
    D *= 3.28084 # convert from m to ft
    L = D * length_to_diameter
    Design['Residence time'] = self.tau
    Design['Reactor volume'] = V_reactor
    Design.update(self._vessel_design(float(P), float(D), float(L)))
    self._decorated_design()

def _cost(self):
    Design = self.design_results
    self.baseline_purchase_costs.update(
        self._vessel_purchase_cost(
            Design['Weight'], Design['Diameter'], Design['Length']
        )
    )
    self._decorated_cost()

Rxn = tmo.reaction.Reaction ParallelRxn = tmo.reaction.ParallelReaction M201 = units.Mixer('M201', [sulfuric_acid, U101-0]) P201 = units.Pump('P201', M201-0, P=1.5101325) H201 = units.HXutility('H201', P201-0, T=110+273.15, V=0) P202 = units.Pump('P202', H201-0, P=2101325) R201 = PretreatmentReactorSystem('R201', P202-0)

A_sys = bst.main_flowsheet.create_system('A_sys') A_sys.simulate() A_sys.diagram('thorough', format='png')

error information:

NotImplementedError Traceback (most recent call last) Cell In [5], line 2 1 A_sys = bst.main_flowsheet.create_system('A_sys') ----> 2 A_sys.simulate() 3 A_sys.diagram('thorough', format='png')

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_system.py:2200, in System.simulate(self, update_configuration, **kwargs) 2198 elif self._facility_loop: 2199 self._facility_loop.converge() -> 2200 return outputs

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_flowsheet.py:36, in TemporaryFlowsheet.exit(self, type, exception, traceback) 34 def exit(self, type, exception, traceback): 35 main_flowsheet.set_flowsheet(self.original) ---> 36 if exception: raise exception

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_system.py:2192, in System.simulate(self, update_configuration, kwargs) 2190 outputs = self.simulate(update_configuration=True, kwargs) 2191 else: -> 2192 raise error 2193 else: 2194 if (not update_configuration # Avoid infinite loop 2195 and self._connections != [i.get_connection() for i in self.streams]): 2196 # Connections has been updated within simulation.

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_system.py:2183, in System.simulate(self, update_configuration, kwargs) 2181 else: 2182 try: -> 2183 outputs = self.converge(kwargs) 2184 self._summary() 2185 except Exception as error:

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_system.py:1904, in System.converge(self, material_data, update_material_data) 1902 for i in range(self._N_runs): method() 1903 else: -> 1904 method() 1905 if update_material_data: 1906 if reset_material_data:

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_system.py:1803, in System.run(self) 1801 f = try_method_with_object_stamp 1802 for i in self._path: -> 1803 if isa(i, Unit): f(i, i.run) 1804 elif isa(i, System): f(i, i.converge) 1805 else: i()

File D:\anaconda\envs\zddx\lib\site-packages\thermosteam\exceptions.py:90, in try_method_with_object_stamp(object, method, args) 88 raise StampedKeyError(message_with_object_stamp(object, repr(error.args[0]))) 89 except Exception as error: ---> 90 raise_error_with_object_stamp(object, error)

File D:\anaconda\envs\zddx\lib\site-packages\thermosteam\exceptions.py:80, in raise_error_with_object_stamp(object, error) 78 error.args = (message_with_object_stamp(object, msg), *args) 79 except: pass ---> 80 raise error

File D:\anaconda\envs\zddx\lib\site-packages\thermosteam\exceptions.py:84, in try_method_with_object_stamp(object, method, args) 82 def try_method_with_object_stamp(object, method, args=()): 83 try: ---> 84 return method(*args) 85 except StampedKeyError as error: 86 raise StampedKeyError(message_with_object_stamp(object, error.args[0]))

File D:\anaconda\envs\zddx\lib\site-packages\biosteam_unit.py:1258, in Unit.run(self) 1256 if self.run_after_specifications: self._run() 1257 else: -> 1258 self._run()

Cell In [3], line 71, in PretreatmentReactorSystem._run(self) 69 ms = self._multistream 70 ms.copy_like(liquid) ---> 71 ms.vle(T=self.T, H=ms.H) 72 vapor.mol[:] = ms.imol['g'] 73 liquid.mol[:] = ms.imol['l']

File D:\anaconda\envs\zddx\lib\site-packages\thermosteam\equilibrium\vle.py:368, in VLE.call(self, T, P, V, H, S, x, y) 366 thermal_condition.T = T 367 elif H_spec: --> 368 self.set_TH(T, H) 369 elif S_spec: 370 self.set_TS(T, S)

File D:\anaconda\envs\zddx\lib\site-packages\thermosteam\equilibrium\vle.py:797, in VLE.set_TH(self, T, H) 795 dH_bubble = (H - H_bubble) 796 if dH_bubble <= 0: --> 797 raise NotImplementedError('cannot solve for pressure yet') 799 # Guess overall vapor fraction, and vapor flow rates 800 V = dH_bubble/(H_dew - H_bubble)

NotImplementedError: cannot solve for pressure yet

yoelcortes commented 1 year ago

@zasddsgg, vle is run on this line:

ms.vle(T=self.T, H=ms.H)

T and H is being given, but T is below the bubble point and there is no pressure at which H would be satisfied. I think you meant to pass T and V.

zasddsgg commented 1 year ago

Thank you for your reminding. I changed ms.vle(T=self.T, H=ms.H) to ms.vle(T=self.T, V=ms.V). After running, the vapor fraction of R201 outlet stream is not 0 set by me, but I have set V=0 in def init, why is there still gas phase in outlet stream. R201 outlet stream information is as follows:

phase: 'g', T: 383.15 K, P: 135818 Pa flow (kmol/hr): Water 0.00475 AceticAcid 0.00475 Furfural 0.00475

yoelcortes commented 1 year ago

@zasddsgg, you should be running ms.vle(T=self.T, V=self.V), then you should get no vapor.

zasddsgg commented 1 year ago

Thank you for your reminding and help. The problem has been solved. Thank you again for your help. Wish you a good day.