Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions src/main/python/utils/UnitOperations.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,9 @@ def OM_Flowsheet_Initialize(self):
self.OM_data_init = ''

if(self.thermo_pack_req):
if len(self.extra)>1:
for i in range(len(self.extra)):
latest = ''
for j in range(self.extra[i]):
if self.extra[i][j]!='.':
latest += self.extra[i][j]
self.for_naming[i] = latest
if len(self.extra)>1:
# Modelica model names cannot contain '.', e.g. 'DistillationColumn.Cond'
self.for_naming = [e.replace('.', '') for e in self.extra]

if(self.thermo_pack_req):
if len(self.extra)==1:
Expand All @@ -133,10 +129,9 @@ def OM_Flowsheet_Initialize(self):
self.OM_data_init += ('extends Simulator.UnitOperations.'+self.extra[i]+';\n')
for j in range(len(self.extra)-1):
self.OM_data_init += (self.for_naming[j] + str(self.counter) +' ' + self.for_naming[j] + '#' + self.multidict[j] + ';\n')
self.OM_data_init += ('end '+self.for_naming[i]+str(self.counter)+';\n')

self.OM_data_init += ('end '+self.for_naming[i]+str(self.counter)+';\n')

self.OM_data_init += self.for_naming[i] + str(self.counter) + ' ' + self.for_naming + '(Nc = ' + str(len(self.compounds))
self.OM_data_init += self.for_naming[-1] + str(self.counter) + ' ' + self.name + '(Nc = ' + str(len(self.compounds))

C = ', '.join(_normalize_compound_name(c) for c in self.compounds)
self.OM_data_init += ',C = {' + C + '}'
Expand Down Expand Up @@ -426,9 +421,12 @@ def OM_Flowsheet_Equation(self):
self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[1].name + '.F_pc[1,:' +
str(self.compounds.index(self.variables['C_Spec']['comp']) + 1) + '] = ' + str(
self.variables['C_Spec']['value']) + ';\n')
else:
elif self.mode:
self.OM_data_eqn = self.OM_data_eqn + (
self.name + '.Condenser.' + self.mode + '=' + str(self.modeVal) + ';\n')
self.name + '.condenser.' + self.mode + '=' + str(self.mode_val) + ';\n')
else:
raise ValueError(
"Unsupported condenser specification: " + str(self.variables['C_Spec']['type']))

if self.variables['R_Spec']['type'] == "Product Molar Flow (mol/s)":
self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[2].name + '.' + 'F_p[1] = ' + str(
Expand Down
55 changes: 54 additions & 1 deletion tests/test_unit_operations.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import sys
import os
import unittest
from types import SimpleNamespace

# Ensure Python can find modules under src/main/python
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src', 'main', 'python')))

from utils.UnitOperations import (
Mixer, Splitter, Heater, Cooler, Flash, CentrifugalPump, Valve,
UnitOperation, Mixer, Splitter, Heater, Cooler, Flash, CentrifugalPump, Valve,
AdiabaticCompressor, AdiabaticExpander, CompoundSeparator,
ShortcutColumn, DistillationColumn, ConvertionReactor
)
from python.utils.ComponentSelector import compound_selected


class TestUnitOperations(unittest.TestCase):
Expand Down Expand Up @@ -172,5 +174,56 @@ def test_conversion_reactor_initialization(self):
self.assertEqual(reactor.no_of_outputs, 1)


class TestUnitOperationCodeGeneration(unittest.TestCase):
"""Regression tests for Modelica code paths that used to crash."""

def setUp(self):
self._saved_compounds = list(compound_selected)
compound_selected[:] = ["Water(chemsep)", "Ethanol(chemsep)"]

def tearDown(self):
compound_selected[:] = self._saved_compounds

def test_initialize_with_multiple_thermo_models(self):
unit = UnitOperation()
unit.name = 'U1'
unit.thermo_pack_req = True
unit.extra = ['DistillationColumn.Cond', 'DistillationColumn.DistCol']
unit.multidict = ['x']
unit.parameters = ['Nt']
unit.variables = {'Nt': {'value': 12}}
c = UnitOperation.counter

self.assertEqual(
unit.OM_Flowsheet_Initialize(),
f'model DistillationColumnCond{c}\n'
'extends Simulator.UnitOperations.DistillationColumn.Cond;\n'
'extends Simulator.Files.ThermodynamicPackages.RaoultsLaw;\n'
f'end DistillationColumnCond{c};\n'
f'model DistillationColumnDistCol{c}\n'
'extends Simulator.UnitOperations.DistillationColumn.DistCol;\n'
f'DistillationColumnCond{c} DistillationColumnCond#x;\n'
f'end DistillationColumnDistCol{c};\n'
f'DistillationColumnDistCol{c} U1(Nc = 2,C = {{Water, Ethanol}}, Nt = 12);\n',
)

def _column_with_condenser_spec(self, spec):
column = DistillationColumn()
column.variables['C_Spec']['type'] = spec
column.input_stms = {1: SimpleNamespace(name='F')}
column.output_stms = {1: SimpleNamespace(name='D'), 2: SimpleNamespace(name='B')}
return column

def test_condenser_fallback_uses_selected_mode(self):
column = self._column_with_condenser_spec('Custom')
column.mode, column.mode_val = 'T', 350
self.assertIn(f'{column.name}.condenser.T=350;\n', column.OM_Flowsheet_Equation())

def test_unknown_condenser_spec_without_mode_raises(self):
column = self._column_with_condenser_spec('Custom')
with self.assertRaisesRegex(ValueError, 'Unsupported condenser specification: Custom'):
column.OM_Flowsheet_Equation()


if __name__ == '__main__':
unittest.main()
Loading