Skip to content

Commit ae3cdd2

Browse files
committed
2.51.11 release; new TEA tables
1 parent 1d45634 commit ae3cdd2

File tree

9 files changed

+91
-27
lines changed

9 files changed

+91
-27
lines changed

Bioindustrial-Park

Submodule Bioindustrial-Park updated 197 files

biosteam/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
"""
1515
from __future__ import annotations
16-
__version__ = '2.51.10'
16+
__version__ = '2.51.11'
1717

1818
#: Chemical engineering plant cost index (defaults to 567.5 at 2017).
1919
CE: float = 567.5

biosteam/_tea.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,41 @@ class TEA:
380380
'India': 0.85,
381381
}
382382

383+
class Accounting:
384+
__slots__ = ('index', 'data', 'names', 'units')
385+
386+
def __init__(self, units, names=None):
387+
self.units = units
388+
self.names = names
389+
self.index = []
390+
self.data =[]
391+
392+
def entry(self, index: str, cost: list|float, notes: str = ''):
393+
self.index.append(index)
394+
if getattr(cost, 'ndim') == 0: cost = float(cost)
395+
if isinstance(cost, (float, int, str)):
396+
self.data.append([notes, cost])
397+
else:
398+
self.data.append([notes, *cost])
399+
400+
@property
401+
def total_costs(self):
402+
if self.names is None:
403+
return sum([i[1] for i in self.data])
404+
else:
405+
N = len(self.data[0])
406+
return [sum([i[index] for i in self.data]) for index in range(1, N)]
407+
408+
def table(self):
409+
names = self.names
410+
units = self.units
411+
index = self.index
412+
return pd.DataFrame(
413+
self.data,
414+
index=pd.MultiIndex.from_tuples(index) if isinstance(index[0], tuple) else index,
415+
columns=('Notes', f'Cost [{units}]') if names is None else ('Notes', [f'{i}\n[{units}]' for i in names]),
416+
)
417+
383418
def __init_subclass__(cls, isabstract=False):
384419
if isabstract: return
385420
for method in ('_DPI', '_TDC', '_FCI', '_FOC'):
@@ -995,6 +1030,21 @@ def solve_price(self, streams: bst.Stream|Collection[bst.Stream]):
9951030
current_price = sum([system.get_market_value(i) for i in streams]) / abs(price2cost)
9961031
return current_price + sales / price2cost
9971032

1033+
def VOC_table(
1034+
self, products, functional_unit='MT', with_products=False,
1035+
):
1036+
return bst.report.voc_table(
1037+
[self.system], products,
1038+
system_names=None, functional_unit=functional_unit,
1039+
with_products=with_products, dataframe=True
1040+
)
1041+
1042+
def CAPEX_table(self):
1043+
return NotImplemented
1044+
1045+
def FOC_table(self):
1046+
return NotImplemented
1047+
9981048
def solve_sales(self):
9991049
"""
10001050
Return the required additional sales [USD] to reach the breakeven

biosteam/_unit.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,10 +1412,11 @@ def addcapex(key):
14121412
addkey(('Design', ki))
14131413
if ki in units:
14141414
ui = units[ki]
1415-
q = Quantity(vi, ui)
1416-
q = q.to_base_units()
1417-
vi = q.magnitude
1418-
ui = q.units
1415+
if ui != 'hr':
1416+
q = Quantity(vi, ui)
1417+
q = q.to_base_units()
1418+
vi = q.magnitude
1419+
ui = q.units
14191420
else:
14201421
ui = ''
14211422
addval((ui, vi))

biosteam/evaluation/_name.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
def element_name(element):
1414
if element:
1515
if isinstance(element, str):
16-
return format_title(element)
16+
return element
1717
elif hasattr(element, 'line'):
1818
return element.line + '-' + format_title(str(element))
1919
else:

biosteam/report/table.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def _reformat(name):
3737
if name.islower(): name= name.capitalize()
3838
return name
3939

40-
# %% Detailed TEA tables
40+
# %%
4141

4242
class FOCTableBuilder:
4343
__slots__ = ('index', 'data', 'costs')
@@ -52,30 +52,37 @@ def entry(self, index, costs, notes='-'):
5252
self.data.append([notes, *costs])
5353
self.costs.append(costs)
5454

55-
def table(self, names):
55+
def table(self, names, dataframe=True):
5656
data = self.data
5757
index = self.index.copy()
5858
index.append('Fixed operating cost (FOC)')
5959
data.append(("", *sum(self.costs)))
60-
return pd.DataFrame(np.array(data),
61-
index=index,
62-
columns=(
63-
'Notes',
64-
*[i + '\n[MM$ / yr]' for i in names],
65-
)
66-
)
67-
60+
columns = ('Notes', *[i + '\n[MM$ / yr]' for i in names])
61+
if dataframe:
62+
return pd.DataFrame(
63+
np.array(data),
64+
index=index,
65+
columns=columns,
66+
)
67+
else:
68+
return data, index, columns
69+
6870
# %% Multiple system tables
6971

70-
def voc_table(systems, product_IDs, system_names=None, unit='MT', with_products=False):
72+
def voc_table(
73+
systems, product_IDs,
74+
system_names=None, functional_unit='MT',
75+
with_products=False, dataframe=True
76+
):
7177
# Not ready for users yet
7278
isa = isinstance
7379
if isa(systems, bst.System): systems = [systems]
7480
if isa(product_IDs, str): product_IDs = [product_IDs]
81+
product_IDs = [(i.ID if hasattr(i, 'ID') else i) for i in product_IDs]
7582
inlet_cost_dct = {}
7683
outlet_revenue_dct = {}
7784
prices = bst.stream_prices
78-
factor = 1 / tmo.units_of_measure.convert(1, 'kg', unit)
85+
factor = 1 / tmo.units_of_measure.convert(1, 'kg', functional_unit)
7986

8087
def getsubdct(dct, name):
8188
if name in dct:
@@ -166,11 +173,17 @@ def reformat(name):
166173
VOC_index = N_rows - N_products - 1
167174
data[VOC_index, 1:] = data[:N_consumed, 1:].sum(axis=0) - data[N_consumed:VOC_index, 1:].sum(axis=0)
168175
if system_names is None:
169-
system_names = [i.ID for i in systems]
170-
columns = [i + " [MM$/yr]" for i in system_names]
171-
return pd.DataFrame(data,
172-
index=pd.MultiIndex.from_tuples(table_index),
173-
columns=(f'Price [$/{unit}]', *columns))
176+
if len(systems) == 1:
177+
columns = ["Cost [MM$/yr]"]
178+
else:
179+
system_names = [i.ID for i in systems]
180+
columns = [i + " [MM$/yr]" for i in system_names]
181+
if dataframe:
182+
return pd.DataFrame(data,
183+
index=pd.MultiIndex.from_tuples(table_index),
184+
columns=(f'Price [$/{functional_unit}]', *columns))
185+
else:
186+
return data, table_index, (f'Price [$/{functional_unit}]', *columns)
174187

175188
def lca_inventory_table(systems, key, items=(), system_names=None):
176189
isa = isinstance

biosteam/units/heat_exchange.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class HX(Unit, isabstract=True):
110110

111111
@property
112112
def material(self):
113-
"""Default 'Carbon steel/carbon steel'"""
113+
"""Default 'Carbon steel/carbon steel'."""
114114
return self._material
115115

116116
@material.setter

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
name='biosteam',
1212
packages=['biosteam'],
1313
license='MIT',
14-
version='2.51.10',
14+
version='2.51.11',
1515
description='The Biorefinery Simulation and Techno-Economic Analysis Modules',
1616
long_description=open('README.rst', encoding='utf-8').read(),
1717
author='Yoel Cortes-Pena',

0 commit comments

Comments
 (0)