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
[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
[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 (
Iterable
[Stream
], optional) – Additional feeds to the process.facilities (
Iterable
[Facility
]) – Offsite facilities that are simulated only after completing the path simulation.ends (
Iterable
[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 (
Iterable
[Unit
], optional) – Unit operations to be included.ends (
Iterable
[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.
- adaptive_phenomena_oriented_simulation#
Whether to run sequential modular simulation when phenomena oriented simulation is not converging.
- property responses#
Unit design decisions that need to converge to satisfy process specifications.
- parameter(setter=None, element=None, coupled=None, name=None, distribution=None, units=None, baseline=None, bounds=None, hook=None, description=None, optimized=False, kind=None)[source]#
Define and register parameter.
- Parameters:
setter (
Callable
, optional) – Should set parameter in the element.element (
Unit
, optional) – Element in the system being altered.coupled (
bool
, optional) – Whether parameter is coupled to the system’s mass and energy balances. This allows a ConvergenceModel to predict it’s impact on recycle loops. Defaults to False.name (
str
, optional) – Name of parameter. If None, default to argument name of setter.distribution (
str
, optional) – Parameter distribution.units (
str
, optional) – Parameter units of measurebaseline (
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.
- 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, facilities=True, **graph_attrs)[source]#
Display a Graphviz diagram of the system.
- Parameters:
kind (
int
, optional) –0 or ‘cluster’: Display all units clustered by system.
1 or ‘thorough’: Display every unit within the system.
2 or ‘surface’: Display only elements listed in the path.
3 or ‘minimal’: Display a single box representing the system.
4 or ‘stage’: Display every stage within the system.
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
[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', sheets=None, stage=False, **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].