Skip to content

Commit

Permalink
more robust indexers
Browse files Browse the repository at this point in the history
  • Loading branch information
yoelcortes committed Nov 22, 2024
1 parent 197807c commit 787ede0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 24 deletions.
1 change: 0 additions & 1 deletion thermosteam/_phase.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def check_phase(phase):
f"invalid phase {repr(phase)} encountered; valid phases are "
"'s' (solid), 'l' (liquid), 'g' (gas), 'S' (SOLID), and 'L' (LIQUID)"
)
return phase

def phase_tuple(phases):
"""
Expand Down
63 changes: 40 additions & 23 deletions thermosteam/indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,27 +633,29 @@ def blank(cls, phase, chemicals=None, parent=None, lock_phase=False):
if parent is None:
self._load_chemicals(chemicals)
self.data = SparseVector.from_size(chemicals.size)
self._data_cache = {}
else:
self._chemicals = parent._chemicals
self.data = parent.data.rows[parent._phase_indexer(phase)]
self._data_cache = {'linked': []}
self._phase = phase
self._lock_phase = lock_phase
self._parent = parent
self._data_cache = {}
return self

@classmethod
def from_data(cls, data, phase=None, chemicals=None, check_data=True, lock_phase=False):
def from_data(cls, data, phase=None, chemicals=None, check_data=True, lock_phase=False, parent=None):
self = _new(cls)
self._load_chemicals(chemicals)
self._phase = check_phase(phase)
self._phase = phase
self.data = data = sparse_vector(data)
if check_data:
assert data.ndim == 1, 'material data must be a 1d numpy array'
assert data.size == self._chemicals.size, ('size of material data must be equal to '
'size of chemicals')
self._data_cache = {}
self._parent = None
check_phase(phase)
self._data_cache = {} if parent is None else {'linked': []}
self._parent = parent
self._lock_phase = lock_phase
return self

Expand All @@ -662,19 +664,21 @@ def phase(self):
return self._phase
@phase.setter
def phase(self, phase):
parent = self._parent
if phase == self._phase: return
if self._lock_phase: raise AttributeError('phase is locked')
check_phase(phase)
parent = self._parent
if parent is None:
self._phase = phase
elif self._lock_phase:
raise AttributeError('phase is locked')
else:
old_data = self.data
self.data = parent.data.rows[index[phase]]
dct = self.data.dct
dct.clear()
dct.update(old_data.dct)
self._phase = phase
for i in self._data_cache['linked']: i.dct = dct

def get_phase_and_composition(self):
"""Return phase and composition."""
Expand Down Expand Up @@ -1001,7 +1005,7 @@ def blank(cls, phases, chemicals=None, parent=None):
return self

@classmethod
def from_data(cls, data, phases, chemicals=None, check_data=True):
def from_data(cls, data, phases, chemicals=None, check_data=True, parent=None):
self = _new(cls)
self._load_chemicals(chemicals)
self._set_phases(phases)
Expand All @@ -1018,7 +1022,7 @@ def from_data(cls, data, phases, chemicals=None, check_data=True):
'must be equal to '
'number of material data columns')
self._data_cache = {}
self._parent = None
self._parent = parent
return self

@property
Expand Down Expand Up @@ -1277,9 +1281,16 @@ def _replace_indexer_doc(Indexer, Parent):
doc = Parent.__doc__
doc = doc[:doc.index("Notes")]
Indexer.__doc__ = doc.replace(Parent.__name__, Indexer.__name__)


@property
def proxy_phase(self):
return self._phase._phase
@proxy_phase.setter
def proxy_phase(self, phase):
self._phase.phase = phase

def _new_Indexer(name, units, f_group_composition):
dct = {'group_compositions': f_group_composition}
dct = {'group_compositions': f_group_composition,}
ChemicalIndexerSubclass = type('Chemical' + name + 'Indexer', (ChemicalIndexer,), dct)
MaterialIndexerSubclass = type(name + 'Indexer', (MaterialIndexer,), dct)

Expand Down Expand Up @@ -1314,25 +1325,29 @@ def group_vol_composition(self):
ChemicalMolarFlowIndexer, MolarFlowIndexer = _new_Indexer('MolarFlow', 'kmol/hr', group_mol_compositions)
ChemicalMassFlowIndexer, MassFlowIndexer = _new_Indexer('MassFlow', 'kg/hr', group_wt_compositions)
ChemicalVolumetricFlowIndexer, VolumetricFlowIndexer = _new_Indexer('VolumetricFlow', 'm^3/hr', group_vol_composition)
ChemicalMassFlowIndexer.phase = proxy_phase
ChemicalVolumetricFlowIndexer.phase = proxy_phase

# %% Mass flow properties

def by_mass(self):
"""Return a ChemicalMassFlowIndexer that references this object's molar data."""
try:
mass = self._data_cache['mass', self._phase]
mass = self._data_cache['mass']
except:
chemicals = self.chemicals
self._data_cache['mass', self._phase] = mass = \
dct = MassFlowDict(self.data.dct, chemicals.MW)
data_cache = self._data_cache
if 'linked' in data_cache: data_cache['linked'].append(dct)
data_cache['mass'] = mass = \
ChemicalMassFlowIndexer.from_data(
SparseVector.from_dict(
MassFlowDict(self.data.dct, chemicals.MW),
dct,
chemicals.size
),
self._phase,
self,
chemicals,
False,
True,
)
return mass
ChemicalMolarFlowIndexer.by_mass = by_mass
Expand Down Expand Up @@ -1369,18 +1384,20 @@ def by_volume(self, TP):
"""
try:
vol = self._data_cache['vol', TP, self._phase]
vol = self._data_cache['vol']
except:
chemicals = self._chemicals
V = [i.V for i in chemicals]
phase = self._phase
self._data_cache['vol', TP, self._phase] = \
dct = VolumetricFlowDict(self.data.dct, TP, V, None, self, {})
data_cache = self._data_cache
if 'linked' in data_cache: data_cache['linked'].append(dct)
data_cache['vol'] = \
vol = ChemicalVolumetricFlowIndexer.from_data(
SparseVector.from_dict(
VolumetricFlowDict(self.data.dct, TP, V, None, self, {}),
dct,
chemicals.size
),
phase, chemicals,
self, chemicals,
False
)
return vol
Expand All @@ -1395,13 +1412,13 @@ def by_volume(self, TP):
"""
try:
vol = self._data_cache[TP]
vol = self._data_cache['vol']
except:
phases = self._phases
chemicals = self._chemicals
V = [i.V for i in chemicals]
size = chemicals.size
self._data_cache[TP] = \
self._data_cache['vol'] = \
vol = VolumetricFlowIndexer.from_data(
SparseArray.from_rows([
SparseVector.from_dict(VolumetricFlowDict(i.dct, TP, V, j, None, {}), size)
Expand Down

0 comments on commit 787ede0

Please sign in to comment.