System#
System objects manage recycle loops. It takes care of bringing a chemical process to steady state.
- class System(ID='', path=(), recycle=None, facilities=(), facility_recycle=None, N_runs=None, operating_hours=None, lang_factor=None, responses=None, algorithm=None, method=None, maxiter=None, molar_tolerance=None, relative_molar_tolerance=None, temperature_tolerance=None, relative_temperature_tolerance=None)[source]#
Create a System object that can iteratively run each element in a path of BioSTREAM objects until the recycle stream is converged. A path can have
Unit
and/orSystem
objects. When the path contains an inner System object, it converges/solves it in each loop/iteration.- Parameters:
ID (
str
, optional) – Unique identification. If ID is None, instance will not be registered in flowsheet.path (
Iterable`[:py:class:`~biosteam.Unit
|System
], optional) – Path that is run element by element until the recycle converges.recycle (
Stream
, optional) – Tear stream for the recycle loop.facilities (
Iterable`[:py:class:`~biosteam.Facility
]) – Offsite facilities that are simulated only after completing the path simulation.facility_recycle (
Stream
, optional) – Recycle stream between facilities and system path.N_runs (
int
, optional) – Number of iterations to converge the system.operating_hours (
float
, optional) – Number of operating hours in a year. This parameter is used to compute annualized properties such as utility cost and material cost on a per year basis.lang_factor (
float
, optional) – Lang factor for getting fixed capital investment from total purchase cost. If no lang factor, installed equipment costs are estimated using bare module factors.
-
default_phenomena_maxiter:
int
= 15# Default maximum number of phenomena-oriented simulations before running each unit operation sequentially
-
default_methods:
dict
[str
] = {'Phenomena oriented': 'fixed-point', 'Sequential modular': 'Aitken'}# Default method for convergence algorithm.
-
available_methods:
Methods
[str
,tuple
[Callable
,bool
,dict
]] = {'aitken': (<function conditional_aitken>, True, {}), 'anderson': (<function root>, False, {'method': 'anderson', 'options': {'fatol': 1e-24, 'ftol': 1e-24, 'maxiter': 1000000, 'xatol': 1e-24, 'xtol': 1e-24}}), 'broyden1': (<function root>, False, {'method': 'broyden1', 'options': {'fatol': 1e-24, 'ftol': 1e-24, 'maxiter': 1000000, 'xatol': 1e-24, 'xtol': 1e-24}}), 'broyden2': (<function root>, False, {'method': 'broyden2', 'options': {'fatol': 1e-24, 'ftol': 1e-24, 'maxiter': 1000000, 'xatol': 1e-24, 'xtol': 1e-24}}), 'diagbroyden': (<function root>, False, {'method': 'diagbroyden', 'options': {'fatol': 1e-24, 'ftol': 1e-24, 'maxiter': 1000000, 'xatol': 1e-24, 'xtol': 1e-24}}), 'excitingmixing': (<function root>, False, {'method': 'excitingmixing', 'options': {'fatol': 1e-24, 'ftol': 1e-24, 'maxiter': 1000000, 'xatol': 1e-24, 'xtol': 1e-24}}), 'fixedpoint': (<function conditional_fixed_point>, True, {}), 'linearmixing': (<function root>, False, {'method': 'linearmixing', 'options': {'fatol': 1e-24, 'ftol': 1e-24, 'maxiter': 1000000, 'xatol': 1e-24, 'xtol': 1e-24}}), 'wegstein': (<function conditional_wegstein>, True, {})}# Method definitions for convergence
- classmethod register_method(name, solver, conditional=False, **kwargs)[source]#
Register new convergence method (root solver). Two solver signatures are supported:
If conditional is False, the signature must be solver(f, x, **kwargs) where f(x) = 0 is the solution. This is common for scipy solvers.
If conditional is True, the signature must be solver(f, x, **kwargs) where f(x) = (x, converged) is the solution and the solver stops when converged is True. This method is prefered in BioSTEAM.
- classmethod from_feedstock(ID='', feedstock=None, feeds=None, facilities=(), ends=None, facility_recycle=None, operating_hours=None, **kwargs)[source]#
Create a System object from a feedstock.
- Parameters:
ID (
str
, optional) – Name of system.feedstock (
Stream
) – Main feedstock of the process.feeds (
Stream
], optional) – Additional feeds to the process.facilities (
Facility
]) – Offsite facilities that are simulated only after completing the path simulation.ends (
Stream
]) – Streams that not products, but are ultimately specified through process requirements and not by its unit source.facility_recycle (
Stream
, optional) – Recycle stream between facilities and system path.operating_hours (
float
, optional) – Number of operating hours in a year. This parameter is used to compute annualized properties such as utility cost and material cost on a per year basis.
- classmethod from_units(ID='', units=None, ends=None, facility_recycle=None, operating_hours=None, **kwargs)[source]#
Create a System object from all units given.
- Parameters:
ID (
str
, optional) – Name of system.units (
Unit
], optional) – Unit operations to be included.ends (
Stream
], optional) – End streams of the system which are not products. Specify this argument if only a section of the complete system is wanted, or if recycle streams should be ignored.facility_recycle (
Stream
, optional) – Recycle stream between facilities and system path. This argument defaults to the outlet of a BlowdownMixer facility (if any).operating_hours (
float
, optional) – Number of operating hours in a year. This parameter is used to compute annualized properties such as utility cost and material cost on a per year basis.
- classmethod from_segment(ID='', start=None, end=None, operating_hours=None, inclusive=False, **kwargs)[source]#
Create a System object from all units in between start and end.
- Parameters:
ID (
str
, optional) – Name of system.start (
Unit
, optional) – Only downstream units from start are included in the system.end (
Unit
, optional) – Only upstream units from end are included in the system.operating_hours (
float
, optional) – Number of operating hours in a year. This parameter is used to compute annualized properties such as utility cost and material cost on a per year basis.inclusive – Whether to include start and end units.
- phenomena_maxiter#
Default maximum number of phenomena-oriented simulations before attempting sequential modular
- simulate_after_specifications#
Whether to simulate system after running all specifications.
- property responses#
Unit design decisions that need to converge to satisfy process specifications.
- parameter(setter=None, element=None, kind=None, name=None, distribution=None, units=None, baseline=None, bounds=None, hook=None, description=None, scale=None)[source]#
Define parameter.
- Parameters:
setter (function) – Should set parameter in the element.
element (Unit or
Stream
) – Element in the system being altered.kind ({'coupled', 'isolated', 'design', 'cost'}, optional) –
‘coupled’: parameter is coupled to the system.
’isolated’: parameter does not affect the system but does affect the element (if any).
’design’: parameter only affects design and/or cost of the element.
name (str, optional) – Name of parameter. If None, default to argument name of setter.
distribution (chaospy.Dist) – Parameter distribution.
units (str, optional) – Parameter units of measure
baseline (float, optional) – Baseline value of parameter.
bounds (tuple[float, float], optional) – Lower and upper bounds of parameter.
hook (Callable, optional) – Should return the new parameter value given the sample.
scale (float, optional) – The sample is multiplied by the scale before setting.
Notes
If kind is ‘coupled’, account for downstream operations. Otherwise, only account for given element. If kind is ‘design’ or ‘cost’, element must be a Unit object.
- set_tolerance(mol=None, rmol=None, T=None, rT=None, subsystems=False, maxiter=None, subfactor=None, method=None, algorithm=None)[source]#
Set the convergence tolerance and convergence method of the system.
- Parameters:
mol (
float
, optional) – Molar tolerance.rmol (
float
, optional) – Relative molar tolerance.T (
float
, optional) – Temperature tolerance.rT (
float
, optional) – Relative temperature tolerance.subsystems (
bool
) – Whether to set tolerance and method of subsystems as well.maxiter (
int
, optional) – Maximum number if iterations.subfactor (
float
, optional) – Factor to rescale tolerance in subsystems.method (
str
, optional) – Numerical method.algorithm (
str
, optional) – Convergence algorithm
- property ins: piping.StreamPorts[piping.InletPort]#
All inlets to the system.
- property outs: piping.StreamPorts[piping.InletPort]#
All outlets to the system.
- load_inlet_ports(inlets, names=None)#
Load inlet ports to system.
- load_outlet_ports(outlets, names=None)#
Load outlet ports to system.
- property LCA#
QSDsan.LCA object linked to the system.
- property specifications: list[ProcessSpecification]#
Process specifications as a list of process specification objects.
- add_bounded_numerical_specification(f=None, *args, **kwargs)#
Add a bounded numerical specification that solves x where f(x) = 0 using an inverse quadratic interpolation solver.
- Parameters:
f (Callable) – Objective function in the form of f(x, *args).
x (float, optional) – Root guess.
x0 (float) – Root bracket. Solution must lie within x0 and x1.
x1 (float) – Root bracket. Solution must lie within x0 and x1.
xtol (float, optional) – Solver stops when the root lies within xtol. Defaults to 0.
ytol (float, optional) – Solver stops when the f(x) lies within ytol of the root. Defaults to 5e-8.
args (tuple, optional) – Arguments to pass to f.
maxiter – Maximum number of iterations. Defaults to 50.
checkiter (bool, optional) – Whether to raise a Runtime error when tolerance could not be satisfied before the maximum number of iterations. Defaults to True.
checkroot (bool, optional) – Whether satisfying both tolerances, xtol and ytol, are required for termination. Defaults to False.
checkbounds (bool, optional) – Whether to raise a ValueError when in a bounded solver when the root is not certain to lie within bounds (i.e. f(x0) * f(x1) > 0.). Defaults to True.
Examples
See also
Notes
This method also works as a decorator.
- add_specification(specification=None, args=(), simulate=None)[source]#
Add a specification.
- Parameters:
Examples
Notes
This method also works as a decorator.
- prioritize_unit(unit)[source]#
Prioritize unit operation to run first within it’s recycle system, if there is one.
- Parameters:
unit (
Unit
) – Unit operation to prioritize.- Raises:
ValueError – When unit is not in the system.
RuntimeError – When prioritization algorithm fails. This should never happen.
Examples
Create a simple recycle loop and prioritize a different unit operation:
>>> from biosteam import main_flowsheet as f, Stream, settings, Mixer, Splitter >>> f.set_flowsheet('simple_recycle_loop') >>> settings.set_thermo(['Water'], cache=True) >>> feedstock = Stream('feedstock', Water=1000) >>> water = Stream('water', Water=10) >>> recycle = Stream('recycle') >>> product = Stream('product') >>> M1 = Mixer('M1', [feedstock, water, recycle]) >>> S1 = Splitter('S1', M1-0, [product, recycle], split=0.5) >>> recycle_loop_sys = f.create_system('recycle_loop_sys') >>> recycle_loop_sys.print() System('recycle_loop_sys', [M1, S1], recycle=S1-1) >>> recycle_loop_sys.prioritize_unit(S1) >>> recycle_loop_sys.print() System('recycle_loop_sys', [S1, M1], recycle=S1-1)
- split(stream, ID_upstream=None, ID_downstream=None)[source]#
Split system in two; upstream and downstream.
- Parameters:
Examples
>>> from biorefineries import cellulosic >>> from biosteam import default >>> cs = cellulosic.Biorefinery() # Create corn stover biorefinery >>> upstream_sys, downstream_sys = cs.cornstover_sys.split(cs.M201-0) >>> upstream_group = upstream_sys.to_unit_group() >>> upstream_group.show() UnitGroup: Unnamed units: U101, H2SO4_storage, T201, M201 >>> downstream_group = downstream_sys.to_unit_group() >>> for i in upstream_group: assert i not in downstream_group.units >>> assert set(upstream_group.units + downstream_group.units) == set(cs.cornstover_sys.units) >>> default() # Reset to biosteam defaults
- property unit_path: list[Unit]#
Unit operations as ordered in the path (some units may be repeated).
- property path: list[Unit | System]#
A path that is run element by element until the recycle(s) converges (if any).
- property method: str#
Iterative convergence accelerator method (‘wegstein’, ‘aitken’, or ‘fixedpoint’).
- property converge_method: str#
Iterative convergence accelerator method (‘wegstein’, ‘aitken’, or ‘fixedpoint’).
- property algorithm: str#
Iterative convergence algorithm (‘Sequatial modular’, or ‘Phenomena oriented’).
Notes
Timulation algorithms are available:
Sequential modular - squentially runs each unit and subsystem until the recycle (i.e. tear) stream convergences.
Phenomena oriented - partitions and linearizes the underlying phenomenological equations for rapid and robust convergence.
- diagram(kind=None, file=None, format=None, display=True, number=None, profile=None, label=None, title=None, auxiliaries=None, **graph_attrs)[source]#
Display a Graphviz diagram of the system.
- Parameters:
kind (
Union`[:py:class:`int
,str
,None
]) –0 or ‘cluster’: Display all units clustered by system.
1 or ‘thorough’: Display every unit within the path.
2 or ‘surface’: Display only elements listed in the path.
3 or ‘minimal’: Display a single box representing all units.
file (
str
, optional) – File name to save diagram.format (
str
, optional) – File format (e.g. “png”, “svg”). Defaults to ‘png’display (
bool
, optional) – Whether to display diagram in console or to return the graphviz object.number (
bool
, optional) – Whether to number unit operations according to their order in the system path.profile (
bool
, optional) – Whether to clock the simulation time of unit operations.label (
bool
, optional) – Whether to label the ID of streams with sources and sinks.auxiliaries (
bool
, optional) – Whether to include auxiliary units.
- run_sequential_modular()[source]#
Run mass and energy balances for each element in the path without costing unit operations.
- run_phenomena()[source]#
Decouple and linearize material, equilibrium, summation, enthalpy, and reaction phenomena and iteratively solve them.
- get_recycle_data()[source]#
Return recycle data defining material flows and conditions of recycle streams.
- converge(recycle_data=None, update_recycle_data=False)[source]#
Converge mass and energy balances. If material data was given, return converged material flows at steady state. Shape will be M by N, where M is the number of recycle streams and N is the number of chemicals.
- Parameters:
recycle_data (
list`[:py:class:`~biosteam._system.RecycleData
]) – Material data to set recycle streams.
See also
System~.get_recycle_data()
Warning
No design, costing, nor facility algorithms are run. To run full simulation algorithm, see
simulate()
.
- rescale(feedstock, ratio)[source]#
Rescale feedstock flow rate and update recycle stream flow rate guesses.
- set_dynamic_tracker(*subjects, **kwargs)[source]#
Set up an
SystemScope
object to track the dynamic data.- Parameters:
*subjects – Any subjects of the system to track, which must have an .scope attribute of type
Scope
.
- property scope: SystemScope#
A tracker of dynamic data of the system, set up with
System
.`set_dynamic_tracker()`
- property DAE#
System-wide differential algebraic equations.
- simulate(update_configuration=None, units=None, design_and_cost=None, **kwargs)[source]#
If system is dynamic, run the system dynamically. Otherwise, converge the path of unit operations to steady state. After running/converging the system, size and cost all unit operations.
- Parameters:
**kwargs – Additional parameters for
dynamic_run()
(if dynamic) orconverge()
(if steady state).update_configuration (
bool
, optional) – Whether to update system configuration if unit connections have changed.units – Unit operations of the system. If given, original unit operations of the system will be replaced.
- dynamic_run(**dynsim_kwargs)[source]#
Run system dynamically without accounting for the cost or environmental impacts of unit operations.
- Parameters:
**dynsim_kwargs –
Dynamic simulation keyword arguments, could include:
- t_spantuple[float, float]
Interval of integration (t0, tf). The solver starts with t=t0 and integrates until it reaches t=tf.
- t_evaliterable(float)
The time points where status will be saved.
- state_reset_hook: str|Callable
Hook function to reset the cache state between simulations for dynamic systems). Can be “reset_cache” or “clear_state” to call System.reset_cache or System.clear_state, or None to avoiding resetting.
- export_state_to: str
If provided with a path, will save the simulated states over time to the given path, supported extensions are “.xlsx”, “.xls”, “csv”, and “tsv”.
- sample_idstr
ID of the samples to run (for results exporting).
- print_msgbool
Whether to print returned message from scipy.
- print_tbool
Whether to print integration time in the console, usually used for debugging.
- solve_ivp_kwargs
All remaining keyword arguments will be passed to
solve_ivp
.
See also
- define_process_impact(key, name, basis, inventory, CF)[source]#
Define a process impact.
- Parameters:
key (
str
) – Impact indicator key.name (
str
) – Name of process impact.basis (
str
) – Functional unit for the characterization factor.inventory (
Callable
) – Should return the annualized (not hourly) inventory flow rate given no parameters. Units should be in basis / yrCF (
float
) – Characterization factor in impact / basis.
- property heat_utilities: tuple[HeatUtility, ...]#
The sum of all heat utilities in the system by agent.
- property power_utility: PowerUtility#
Sum of all power utilities in the system.
- get_inlet_cost_flows()[source]#
Return a dictionary with flow rates for inlet streams with fees/credits/utilities.
- get_outlet_revenue_flows()[source]#
Return a dictionary with flow rates for outlet streams with fees/credits/utilities.
- get_inlet_flow(units, key=None)[source]#
Return total flow across all inlets per year.
- Parameters:
Examples
>>> from biosteam import Stream, Mixer, Splitter, settings, main_flowsheet >>> settings.set_thermo(['Water', 'Ethanol']) >>> main_flowsheet.clear() >>> S1 = Splitter('S1', Stream(Ethanol=10, units='ton/hr'), split=0.1) >>> M1 = Mixer('M1', ins=[Stream(Water=10, units='ton/hr'), S1-0]) >>> sys = main_flowsheet.create_system(operating_hours=330*24) >>> sys.get_inlet_flow('Mton') # Sum of all chemicals 0.1584 >>> sys.get_inlet_flow('Mton', 'Water') # Just water 0.0792
- get_outlet_flow(units, key=None)[source]#
Return total flow across all outlets per year.
- Parameters:
Examples
>>> from biosteam import Stream, Mixer, Splitter, settings, main_flowsheet >>> settings.set_thermo(['Water', 'Ethanol']) >>> main_flowsheet.clear() >>> S1 = Splitter('S1', Stream(Ethanol=10, units='ton/hr'), split=0.1) >>> M1 = Mixer('M1', ins=[Stream(Water=10, units='ton/hr'), S1-0]) >>> sys = main_flowsheet.create_system(operating_hours=330*24) >>> sys.simulate() >>> sys.get_outlet_flow('Mton') # Sum of all chemicals 0.1584 >>> sys.get_outlet_flow('Mton', 'Water') # Just water 0.0792
- get_total_feeds_impact(key)[source]#
Return the total annual impact of all feeds given the impact indicator key.
- get_total_products_impact(key)[source]#
Return the total annual impact of all products given the impact indicator key.
- get_material_impact(stream, key)[source]#
Return the annual material impact given the stream and the impact indicator key.
- get_total_input_impact(key)[source]#
Return total annual impact of inputs given the impact indicator key.
- get_net_impact(key)[source]#
Return net annual impact, including displaced impacts, given the impact indicator key.
- save_report(file='report.xlsx', dpi='900', **stream_properties)[source]#
Save a system report as an xlsx file.
- debug()[source]#
Simulate in debug mode. If an exception is raised, it will automatically enter in a breakpoint.
- profile()[source]#
Simulate system in profile mode and return a DataFrame object of unit operation simulation times.
- show(layout=None, T=None, P=None, flow=None, composition=None, N=None, IDs=None, sort=None, data=True)[source]#
Prints information on system.
- property ID#
Unique identification (str). If set as ‘’, it will choose a default ID.
- get_ash_disposal_cost()#
Return the ash disposal cost [USD/yr].
- get_ash_disposal_flow()#
Return the ash disposal flow rate [kg/yr].
- get_fuel_cost()#
Return the fuel cost [USD/yr].
- get_fuel_flow()#
Return the fuel flow rate [kg/yr].
- get_natural_gas_cost()#
Return the natural gas cost [USD/yr].
- get_natural_gas_flow()#
Return the natural gas flow rate [kg/yr].
- get_process_water_cost()#
Return the process water cost [USD/yr].
- get_process_water_flow()#
Return the process water flow rate [kg/yr].
- get_reverse_osmosis_water_cost()#
Return the reverse osmosis water cost [USD/yr].
- get_reverse_osmosis_water_flow()#
Return the reverse osmosis water flow rate [kg/yr].