Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions about units operations #184

Open
1226Wang1226 opened this issue Jan 7, 2025 · 6 comments
Open

Questions about units operations #184

1226Wang1226 opened this issue Jan 7, 2025 · 6 comments

Comments

@1226Wang1226
Copy link

Q1. System Simulation Issue
I am unable to simulate the entire system (sys.simulate() fails). The problem seems to originate from the absorber and stripper units. However, I am uncertain how to identify or address the specific issues.
Here is the error message:
TypingError Traceback (most recent call last)
Cell In[2], line 79
77 additional_MEA_needed = required_MEA_mass - total_MEA
78 hx4=bst.HXutility('HX4',ins=M1-0,outs=makeup,T=318.15)
---> 79 sys.simulate()
80 sys.diagram(number=True, kind='cluster')

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_system.py:2793, in System.simulate(self, update_configuration, units, design_and_cost, **kwargs)
2773 def simulate(self, update_configuration: Optional[bool]=None, units=None,
2774 design_and_cost=None, **kwargs):
2775 """
2776 If system is dynamic, run the system dynamically. Otherwise, converge
2777 the path of unit operations to steady state. After running/converging
(...)
2791
2792 """
-> 2793 with self.flowsheet:
2794 specifications = self._specifications
2795 if specifications and not self._running_specifications:

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_flowsheet.py:120, in Flowsheet.exit(self, type, exception, traceback)
118 def exit(self, type, exception, traceback):
119 main_flowsheet.set_flowsheet(self._temporary_stack.pop())
--> 120 if exception: raise exception

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_system.py:2849, in System.simulate(self, update_configuration, units, design_and_cost, **kwargs)
2843 outputs = self.simulate(
2844 update_configuration=True,
2845 design_and_cost=design_and_cost,
2846 **kwargs
2847 )
2848 else:
-> 2849 raise error
2850 else:
2851 if (not update_configuration # Avoid infinite loop
2852 and self._connections != [i.get_connection() for i in self.streams]):
2853 # Connections has been updated within simulation.

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_system.py:2837, in System.simulate(self, update_configuration, units, design_and_cost, **kwargs)
2835 try:
2836 outputs = self.converge(**kwargs)
-> 2837 if design_and_cost: self._summary()
2838 except Exception as error:
2839 if update_configuration: raise error # Avoid infinite loop

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_system.py:2550, in System._summary(self)
2548 if i in simulated_units: continue
2549 simulated_units.add(i)
-> 2550 f(i, i._summary)
2551 for i in self._facilities:
2552 if isa(i, Unit): f(i, i.simulate)

File ~/anaconda3/lib/python3.12/site-packages/thermosteam/exceptions.py:94, in try_method_with_object_stamp(object, method, args)
92 raise StampedKeyError(message_with_object_stamp(object, repr(error.args[0])))
93 except Exception as error:
---> 94 raise_error_with_object_stamp(object, error)

File ~/anaconda3/lib/python3.12/site-packages/thermosteam/exceptions.py:84, in raise_error_with_object_stamp(object, error)
82 error.args = (message_with_object_stamp(object, msg), *args)
83 except: pass
---> 84 raise error

File ~/anaconda3/lib/python3.12/site-packages/thermosteam/exceptions.py:88, in try_method_with_object_stamp(object, method, args)
86 def try_method_with_object_stamp(object, method, args=()):
87 try:
---> 88 return method(*args)
89 except StampedKeyError as error:
90 raise StampedKeyError(message_with_object_stamp(object, error.args[0]))

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_system.py:2550, in System._summary(self)
2548 if i in simulated_units: continue
2549 simulated_units.add(i)
-> 2550 f(i, i._summary)
2551 for i in self._facilities:
2552 if isa(i, Unit): f(i, i.simulate)

File ~/anaconda3/lib/python3.12/site-packages/thermosteam/exceptions.py:94, in try_method_with_object_stamp(object, method, args)
92 raise StampedKeyError(message_with_object_stamp(object, repr(error.args[0])))
93 except Exception as error:
---> 94 raise_error_with_object_stamp(object, error)

File ~/anaconda3/lib/python3.12/site-packages/thermosteam/exceptions.py:84, in raise_error_with_object_stamp(object, error)
82 error.args = (message_with_object_stamp(object, msg), *args)
83 except: pass
---> 84 raise error

File ~/anaconda3/lib/python3.12/site-packages/thermosteam/exceptions.py:88, in try_method_with_object_stamp(object, method, args)
86 def try_method_with_object_stamp(object, method, args=()):
87 try:
---> 88 return method(*args)
89 except StampedKeyError as error:
90 raise StampedKeyError(message_with_object_stamp(object, error.args[0]))

File ~/anaconda3/lib/python3.12/site-packages/biosteam/_unit.py:1205, in Unit._summary(self, design_kwargs, cost_kwargs, lca_kwargs)
1203 if not (self._design or self._cost): return
1204 if not self._skip_simulation_when_inlets_are_empty or not all([i.isempty() for i in self._ins]):
-> 1205 self._design(**design_kwargs) if design_kwargs else self._design()
1206 self._cost(**cost_kwargs) if cost_kwargs else self._cost()
1207 self._lca(**lca_kwargs) if lca_kwargs else self._lca()

File ~/anaconda3/lib/python3.12/site-packages/biosteam/units/distillation.py:2300, in AdiabaticMultiStageVLEColumn._design(self)
2298 rho_V = vapor_out.rho
2299 L = liquid_out.F_mass # To get liquid going down
-> 2300 F_LV = design.compute_flow_parameter(L, V, rho_V, rho_L)
2301 C_sbf = design.compute_max_capacity_parameter(TS, F_LV)
2302 sigma = liquid_out.get_property('sigma', 'dyn/cm')

File ~/anaconda3/lib/python3.12/site-packages/numba/core/dispatcher.py:423, in _DispatcherBase._compile_for_args(self, *args, **kws)
419 msg = (f"{str(e).rstrip()} \n\nThis error may have been caused "
420 f"by the following argument(s):\n{args_str}\n")
421 e.patch_message(msg)
--> 423 error_rewrite(e, 'typing')
424 except errors.UnsupportedError as e:
425 # Something unsupported is present in the user code, add help info
426 error_rewrite(e, 'unsupported_error')

File ~/anaconda3/lib/python3.12/site-packages/numba/core/dispatcher.py:364, in _DispatcherBase._compile_for_args..error_rewrite(e, issue_type)
362 raise e
363 else:
--> 364 raise e.with_traceback(None)

TypingError: <System: SYS2> <AdiabaticMultiStageVLEColumn: U105> Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function() found for signature:

truediv(none, none)

There are 8 candidate implementations:

  • Of which 6 did not match due to:
    Overload of function 'truediv': File: : Line N/A.
    With argument(s): '(none, none)':
    No match.
  • Of which 2 did not match due to:
    Operator Overload in function 'truediv': File: unknown: Line unknown.
    With argument(s): '(none, none)':
    No match for registered cases:
    • (int64, int64) -> float64
    • (int64, uint64) -> float64
    • (uint64, int64) -> float64
    • (uint64, uint64) -> float64
    • (float32, float32) -> float32
    • (float64, float64) -> float64
    • (complex64, complex64) -> complex64
    • (complex128, complex128) -> complex128

During: typing of intrinsic-call at /Users/ershi/anaconda3/lib/python3.12/site-packages/biosteam/units/design_tools/column_design.py (309)

File "anaconda3/lib/python3.12/site-packages/biosteam/units/design_tools/column_design.py", line 309:
def compute_flow_parameter(L, V, rho_V, rho_L):

"""
return L/V*(rho_V/rho_L)**0.5
^

Q2. Heat Exchanger Input/Output Issue
the heat exchanger I am using in my model allows only a single inlet and a single outlet. However, I need to modify it so that the heat exchanger can handle two inlets and two outlets.
The current heat exchanger allows only a single inlet and a single outlet, but i need two inlets and two outlets. Just like this:
image
image

Q3. Valve not displaying
I added a valve unit to the flowsheet, but it is not showing up in the diagram. Could this be due to a visualization issue?
image

Here is my code:
ques.txt

Thank you for your help!!

@yoelcortes
Copy link
Member

@1226Wang1226,

Happy to help:

  1. Valve is an abstract class (not meant for the user). I will plan on changing the name later so others do not get confused. Use IsenthalpicValve instead.
  2. Use HXprocess (HXutility exchanges heat with a utility; HXprocess exchanges heat between process streams). This one has two inlets and two outlets.
  3. The diagram of the valve seems to be broken (it shows only as box), I will look into it.

By the way, the specification on M1 does not do anything:

    @M1.add_specification(run=True, args=[0.30])
    def adjust_MEA_content(MEA_fraction):
        MEA_in_amine=amine.imass['Monoethanolamine']
        MEA_in_liquid=liquid.imass['Monoethanolamine']
        total_MEA = MEA_in_amine + MEA_in_liquid
        total_in_mass = sum(stream.F_mass for stream in M1.ins)
        required_MEA_mass= MEA_fraction * total_in_mass
        additional_MEA_needed = required_MEA_mass - total_MEA # This variable is not used anywhere! Did you mean to add flow somewhere?

The process is still not converging, but I can have a look at it once you feel it is complete (fixed specification, heat exchanger, etc.).

Thanks,

@1226Wang1226
Copy link
Author

@yoelcortes,
Thank you again! And here is my new code:
ques.txt
I fixed M1 specification(i think), and it's still have problem when i simulate😢

@yoelcortes
Copy link
Member

@1226Wang1226, thanks for the follow up. There was an error when creating diagrams with process heat exchangers with missing streams (quite an oddly specific error, I know). Please pip install biosteam==2.50.1 and pip install thermoteam==0.50.1 to fix it.

I made minor changes to your code and get the following diagram. I think some streams are not connected well:

deleteme

import biosteam as bst
bst.main_flowsheet.set_flowsheet('Chemical_scrubbing_biogas')
chemicals = bst.Chemicals(
    ['Water', 'CO2', 'CH4', 'H2S', 'N2', 'O2','Monoethanolamine']
)
bst.settings.set_thermo(chemicals)
bst.settings.mixture.include_excess_energies = True 
raw_biogas=bst.Stream(
'raw_biogas',
CH4=214.84,
CO2=382.8,
H2S=0.228,
N2=3.12,
O2=3.57,
T=298.15,
P=101325,
total_flow=500,
units='kg/hr',
phase='g'
)

amine=bst.Stream('amine',Monoethanolamine=200, units='kmol/hr',phase='l')
gas_rec=bst.Stream('gas_rec',
)
air_in=bst.Stream('air_in',
N2=987.91,
O2=299.96,
units='kg/hr',
phase='g'
)
sol_fl = bst.Stream('sol_fl')
rich_solution = bst.Stream('rich_solution',
CO2=614.26,
CH4=11.29,
H2S=0.27,
N2=0.073,
O2=0.16,
H2O=84365,
units='kg/hr',
phase='l',
P=1e6
)
gas_out=bst.Stream('gas_out')
gas_exit=bst.Stream('gas_exit')
cooledbg=bst.Stream('cooledbg')
gasrec=bst.Stream('gasrec')
makeup=bst.Stream('makeup')
fresh_water=bst.Stream('fresh_water', water=2000, units='kg/hr')
process_water=bst.Stream('process_water')
water_rec=bst.Stream('water_rec', water=82370,units='kg/hr')
water=bst.Stream('water')
liquid=bst.Stream('liquid')
with bst.System() as sys:
    U101 = bst.IsentropicCompressor('U101',raw_biogas, outs='raw_biogas_0',P=150000, eta=0.75)
    hx1=bst.HXutility('HX1', ins=U101-0, outs='raw_biogas_1', T=308.15)
    P1=bst.Pump('P1',ins=makeup,P=150000)
    U102 = bst.Absorber(
        'U104', T=308.15,
        N_stages=9, ins=[P1-0, cooledbg], solute="CO2", outs=('biomethane_outlet','rich_amine'), 
        P=150000
    )
    raw_biogas.set_feed_priority(0) 
    fresh_water.empty() 
    hx2 = bst.HXprocess('HX2', ins=[U102-1, liquid], outs=['heated_amine','lean_amine'])  
    P2 = bst.Pump('P2',ins=hx2-0,P=300000)
    U103 = bst.Stripper('U103',T=393.15, N_stages=9, solute="CO2",ins=P2-0,outs=('gas',liquid),P=300000)
    M1 = bst.Mixer('M1',ins=[amine, water, hx2-1])
    @M1.add_specification(run=True, args=[0.30], impacted_units=[amine.sink])
    def adjust_MEA_content(MEA_fraction):
        MEA_in_amine=amine.imass['Monoethanolamine']
        MEA_in_liquid=liquid.imass['Monoethanolamine']
        total_MEA = MEA_in_amine + MEA_in_liquid
        total_in_mass = sum(stream.F_mass for stream in M1.ins)
        required_MEA_mass= MEA_fraction * total_in_mass
        additional_MEA_needed = required_MEA_mass - total_MEA
        amine.imass['Monoethanolamine'] += additional_MEA_needed
    hx3=bst.HXutility('HX3',ins=M1-0,outs=makeup,T=318.02)
sys.diagram(number=True, kind='cluster')
sys.simulate()

@1226Wang1226
Copy link
Author

@yoelcortes, really thank you about your help. I made a very simple mistake, but i've already fixed it:
112.txt
image
But still can't simulate. Is that the reason that I didn't assign a specific flow rate to the 'water' stream?

@yoelcortes
Copy link
Member

@1226Wang1226, I believe it has to do with your specification. I am getting the following after running your code:

>>> sys.flowsheet.amine.show()
Stream: amine to <Mixer: M1>
phase: 'l', T: 298.15 K, P: 101325 Pa
flow (kmol/hr): Monoethanolamine  -0.408

By the way did you know all streams/units are available in the flowsheet?

>>> import biosteam as bst
>>> bst.F.M1 # Give it a shot after running your code!

I will let you scratch your head a bit with the specification. Tip: you'll need to make sure there are not negative flows being set (consider using max(value, 0)).

Thanks,

@1226Wang1226
Copy link
Author

@yoelcortes, thank you to pointing that out! I’ll take some time to think it through carefully. 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants