ahuora-builder 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ahuora_builder/__init__.py +0 -0
- ahuora_builder/arc_manager.py +33 -0
- ahuora_builder/build_state.py +57 -0
- ahuora_builder/custom/PIDController.py +494 -0
- ahuora_builder/custom/PySMOModel.py +178 -0
- ahuora_builder/custom/SimpleEffectivenessHX_DH.py +727 -0
- ahuora_builder/custom/__init__.py +0 -0
- ahuora_builder/custom/add_initial_dynamics.py +35 -0
- ahuora_builder/custom/custom_compressor.py +107 -0
- ahuora_builder/custom/custom_cooler.py +33 -0
- ahuora_builder/custom/custom_heat_exchanger.py +183 -0
- ahuora_builder/custom/custom_heat_exchanger_1d.py +258 -0
- ahuora_builder/custom/custom_heater.py +41 -0
- ahuora_builder/custom/custom_pressure_changer.py +34 -0
- ahuora_builder/custom/custom_pump.py +107 -0
- ahuora_builder/custom/custom_separator.py +371 -0
- ahuora_builder/custom/custom_tank.py +133 -0
- ahuora_builder/custom/custom_turbine.py +132 -0
- ahuora_builder/custom/custom_valve.py +300 -0
- ahuora_builder/custom/custom_variable.py +29 -0
- ahuora_builder/custom/direct_steam_injection.py +371 -0
- ahuora_builder/custom/energy/__init__.py +0 -0
- ahuora_builder/custom/energy/acBus.py +280 -0
- ahuora_builder/custom/energy/ac_property_package.py +279 -0
- ahuora_builder/custom/energy/battery.py +170 -0
- ahuora_builder/custom/energy/bus.py +182 -0
- ahuora_builder/custom/energy/energy_mixer.py +195 -0
- ahuora_builder/custom/energy/energy_splitter.py +228 -0
- ahuora_builder/custom/energy/grid.py +173 -0
- ahuora_builder/custom/energy/hydro.py +169 -0
- ahuora_builder/custom/energy/link.py +137 -0
- ahuora_builder/custom/energy/load.py +155 -0
- ahuora_builder/custom/energy/mainDistributionBoard.py +257 -0
- ahuora_builder/custom/energy/power_property_package.py +253 -0
- ahuora_builder/custom/energy/solar.py +176 -0
- ahuora_builder/custom/energy/storage.py +230 -0
- ahuora_builder/custom/energy/storage_wrapper +0 -0
- ahuora_builder/custom/energy/tests/__init__.py +0 -0
- ahuora_builder/custom/energy/tests/test_bus.py +44 -0
- ahuora_builder/custom/energy/tests/test_energy_mixer.py +46 -0
- ahuora_builder/custom/energy/tests/test_mdb.py +49 -0
- ahuora_builder/custom/energy/transformer.py +187 -0
- ahuora_builder/custom/energy/transformer_property_package.py +267 -0
- ahuora_builder/custom/energy/transmissionLine.py +228 -0
- ahuora_builder/custom/energy/wind.py +206 -0
- ahuora_builder/custom/hda_ideal_VLE.py +1341 -0
- ahuora_builder/custom/hda_reaction.py +182 -0
- ahuora_builder/custom/heat_exchanger_1d_wrapper.py +31 -0
- ahuora_builder/custom/integration_block.py +106 -0
- ahuora_builder/custom/inverted.py +81 -0
- ahuora_builder/custom/performance_curves.py +1 -0
- ahuora_builder/custom/reactions/__init__.py +0 -0
- ahuora_builder/custom/reactions/hda_stoich.py +10 -0
- ahuora_builder/custom/simple_separator.py +680 -0
- ahuora_builder/custom/tests/__init__.py +0 -0
- ahuora_builder/custom/tests/test_SimpleEffectivenessHX_DH.py +91 -0
- ahuora_builder/custom/tests/test_custom_tank.py +70 -0
- ahuora_builder/custom/tests/test_direct_steam_injection.py +41 -0
- ahuora_builder/custom/tests/test_simple_separator.py +46 -0
- ahuora_builder/custom/tests/test_waterpipe.py +46 -0
- ahuora_builder/custom/thermal_utility_systems/desuperheater.py +624 -0
- ahuora_builder/custom/thermal_utility_systems/header.py +889 -0
- ahuora_builder/custom/thermal_utility_systems/simple_heat_pump.py +567 -0
- ahuora_builder/custom/thermal_utility_systems/steam_header.py +353 -0
- ahuora_builder/custom/thermal_utility_systems/steam_user.py +944 -0
- ahuora_builder/custom/thermal_utility_systems/temp.py +349 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_desuperheater.py +142 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_header.py +998 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_ntu_hx.py +129 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_simple_heat_pump.py +120 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_steam_header.py +703 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_steam_user.py +277 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_waterpipe.py +36 -0
- ahuora_builder/custom/thermal_utility_systems/tests/test_willans_turbine.py +253 -0
- ahuora_builder/custom/thermal_utility_systems/willans_turbine.py +804 -0
- ahuora_builder/custom/translator.py +129 -0
- ahuora_builder/custom/updated_pressure_changer.py +1404 -0
- ahuora_builder/custom/valve_wrapper.py +38 -0
- ahuora_builder/custom/water_tank_with_units.py +456 -0
- ahuora_builder/diagnostics/__init__.py +0 -0
- ahuora_builder/diagnostics/infeasibilities.py +40 -0
- ahuora_builder/diagnostics/tests/__init__.py +0 -0
- ahuora_builder/diagnostics/tests/test_infeasibilities.py +28 -0
- ahuora_builder/flowsheet_manager.py +542 -0
- ahuora_builder/flowsheet_manager_type.py +20 -0
- ahuora_builder/generate_python_file.py +440 -0
- ahuora_builder/methods/BlockContext.py +84 -0
- ahuora_builder/methods/__init__.py +0 -0
- ahuora_builder/methods/adapter.py +355 -0
- ahuora_builder/methods/adapter_library.py +549 -0
- ahuora_builder/methods/adapter_methods.py +80 -0
- ahuora_builder/methods/expression_parsing.py +105 -0
- ahuora_builder/methods/load_unit_model.py +147 -0
- ahuora_builder/methods/slice_manipulation.py +7 -0
- ahuora_builder/methods/tests/__init__.py +0 -0
- ahuora_builder/methods/tests/test_expression_parsing.py +15 -0
- ahuora_builder/methods/units_handler.py +129 -0
- ahuora_builder/ml_wizard.py +101 -0
- ahuora_builder/port_manager.py +20 -0
- ahuora_builder/properties_manager.py +44 -0
- ahuora_builder/property_package_manager.py +78 -0
- ahuora_builder/solver.py +38 -0
- ahuora_builder/tear_manager.py +98 -0
- ahuora_builder/tests/__init__.py +0 -0
- ahuora_builder/tests/test_generate_python_file/__init__.py +0 -0
- ahuora_builder/tests/test_generate_python_file/configurations/compressor_generated.py +63 -0
- ahuora_builder/tests/test_generate_python_file/configurations/heat_exchanger_generated.py +70 -0
- ahuora_builder/tests/test_generate_python_file/configurations/pump_generated.py +84 -0
- ahuora_builder/tests/test_generate_python_file/configurations/recycle_generated.py +73 -0
- ahuora_builder/tests/test_generate_python_file/test_generate_python_file.py +108 -0
- ahuora_builder/tests/test_solver/__init__.py +0 -0
- ahuora_builder/tests/test_solver/configurations/BT_PR.json +59 -0
- ahuora_builder/tests/test_solver/configurations/BT_PR_solved.json +59 -0
- ahuora_builder/tests/test_solver/configurations/bus.json +99 -0
- ahuora_builder/tests/test_solver/configurations/bus_solved.json +50 -0
- ahuora_builder/tests/test_solver/configurations/compound_separator.json +377 -0
- ahuora_builder/tests/test_solver/configurations/compound_separator_solved.json +374 -0
- ahuora_builder/tests/test_solver/configurations/compressor.json +38 -0
- ahuora_builder/tests/test_solver/configurations/compressor_solved.json +68 -0
- ahuora_builder/tests/test_solver/configurations/constraints.json +44 -0
- ahuora_builder/tests/test_solver/configurations/constraints_solved.json +59 -0
- ahuora_builder/tests/test_solver/configurations/control.json +39 -0
- ahuora_builder/tests/test_solver/configurations/control_solved.json +68 -0
- ahuora_builder/tests/test_solver/configurations/dynamic_tank.json +733 -0
- ahuora_builder/tests/test_solver/configurations/dynamic_tank_solved.json +846 -0
- ahuora_builder/tests/test_solver/configurations/elimination.json +39 -0
- ahuora_builder/tests/test_solver/configurations/elimination_solved.json +68 -0
- ahuora_builder/tests/test_solver/configurations/expressions.json +68 -0
- ahuora_builder/tests/test_solver/configurations/expressions_solved.json +104 -0
- ahuora_builder/tests/test_solver/configurations/header.json +1192 -0
- ahuora_builder/tests/test_solver/configurations/header_solved.json +761 -0
- ahuora_builder/tests/test_solver/configurations/heat_exchanger.json +63 -0
- ahuora_builder/tests/test_solver/configurations/heat_exchanger_solved.json +104 -0
- ahuora_builder/tests/test_solver/configurations/heat_pump.json +137 -0
- ahuora_builder/tests/test_solver/configurations/heat_pump_solved.json +104 -0
- ahuora_builder/tests/test_solver/configurations/machine_learning.json +2156 -0
- ahuora_builder/tests/test_solver/configurations/machine_learning_solved.json +266 -0
- ahuora_builder/tests/test_solver/configurations/mass_flow_tear.json +77 -0
- ahuora_builder/tests/test_solver/configurations/mass_flow_tear_solved.json +68 -0
- ahuora_builder/tests/test_solver/configurations/milk_heater.json +521 -0
- ahuora_builder/tests/test_solver/configurations/milk_heater_solved.json +311 -0
- ahuora_builder/tests/test_solver/configurations/mixer.json +44 -0
- ahuora_builder/tests/test_solver/configurations/mixer_solved.json +86 -0
- ahuora_builder/tests/test_solver/configurations/optimization.json +62 -0
- ahuora_builder/tests/test_solver/configurations/optimization_solved.json +59 -0
- ahuora_builder/tests/test_solver/configurations/propane_heat_pump.json +167 -0
- ahuora_builder/tests/test_solver/configurations/propane_heat_pump_solved.json +158 -0
- ahuora_builder/tests/test_solver/configurations/propane_recycle.json +141 -0
- ahuora_builder/tests/test_solver/configurations/propane_recycle_solved.json +104 -0
- ahuora_builder/tests/test_solver/configurations/pump.json +64 -0
- ahuora_builder/tests/test_solver/configurations/pump_solved.json +59 -0
- ahuora_builder/tests/test_solver/configurations/pump_unit_conversions.json +63 -0
- ahuora_builder/tests/test_solver/configurations/recycle.json +49 -0
- ahuora_builder/tests/test_solver/configurations/recycle_solved.json +50 -0
- ahuora_builder/tests/test_solver/configurations/sb_vapor_frac.json +29 -0
- ahuora_builder/tests/test_solver/configurations/sb_vapor_frac_solved.json +29 -0
- ahuora_builder/tests/test_solver/configurations/solar.json +67 -0
- ahuora_builder/tests/test_solver/configurations/solar_solved.json +50 -0
- ahuora_builder/tests/test_solver/configurations/vapor_frac_target.json +67 -0
- ahuora_builder/tests/test_solver/configurations/vapor_frac_target_solved.json +68 -0
- ahuora_builder/tests/test_solver/test_solve_models.py +250 -0
- ahuora_builder/timing.py +65 -0
- ahuora_builder/types/__init__.py +1 -0
- ahuora_builder/unit_model_manager.py +48 -0
- ahuora_builder-0.1.0.dist-info/METADATA +14 -0
- ahuora_builder-0.1.0.dist-info/RECORD +167 -0
- ahuora_builder-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Import Pyomo libraries
|
|
2
|
+
from pyomo.environ import (
|
|
3
|
+
Var,
|
|
4
|
+
Suffix,
|
|
5
|
+
units as pyunits,
|
|
6
|
+
)
|
|
7
|
+
from pyomo.common.config import ConfigBlock, ConfigValue, In
|
|
8
|
+
|
|
9
|
+
# Import IDAES cores
|
|
10
|
+
from idaes.core import (
|
|
11
|
+
declare_process_block_class,
|
|
12
|
+
UnitModelBlockData,
|
|
13
|
+
useDefault,
|
|
14
|
+
)
|
|
15
|
+
from idaes.core.util.config import is_physical_parameter_block
|
|
16
|
+
import idaes.core.util.scaling as iscale
|
|
17
|
+
import idaes.logger as idaeslog
|
|
18
|
+
|
|
19
|
+
from idaes.core.util.tables import create_stream_table_dataframe
|
|
20
|
+
|
|
21
|
+
from idaes.core.util.exceptions import ConfigurationError
|
|
22
|
+
|
|
23
|
+
# Set up logger
|
|
24
|
+
_log = idaeslog.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# When using this file the name "Solar" is what is imported
|
|
28
|
+
@declare_process_block_class("Hydro")
|
|
29
|
+
class HydroData(UnitModelBlockData):
|
|
30
|
+
"""
|
|
31
|
+
Zero order Link model
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# CONFIG are options for the unit model, this simple model only has the mandatory config options
|
|
35
|
+
CONFIG = ConfigBlock()
|
|
36
|
+
|
|
37
|
+
CONFIG.declare(
|
|
38
|
+
"dynamic",
|
|
39
|
+
ConfigValue(
|
|
40
|
+
domain=In([False]),
|
|
41
|
+
default=False,
|
|
42
|
+
description="Dynamic model flag - must be False",
|
|
43
|
+
doc="""Indicates whether this model will be dynamic or not,
|
|
44
|
+
**default** = False. The Bus unit does not support dynamic
|
|
45
|
+
behavior, thus this must be False.""",
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
CONFIG.declare(
|
|
49
|
+
"has_holdup",
|
|
50
|
+
ConfigValue(
|
|
51
|
+
default=False,
|
|
52
|
+
domain=In([False]),
|
|
53
|
+
description="Holdup construction flag - must be False",
|
|
54
|
+
doc="""Indicates whether holdup terms should be constructed or not.
|
|
55
|
+
**default** - False. The Bus unit does not have defined volume, thus
|
|
56
|
+
this must be False.""",
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
CONFIG.declare(
|
|
60
|
+
"property_package",
|
|
61
|
+
ConfigValue(
|
|
62
|
+
default=useDefault,
|
|
63
|
+
domain=is_physical_parameter_block,
|
|
64
|
+
description="Property package to use for control volume",
|
|
65
|
+
doc="""Property parameter object used to define property calculations,
|
|
66
|
+
**default** - useDefault.
|
|
67
|
+
**Valid values:** {
|
|
68
|
+
**useDefault** - use default package from parent model or flowsheet,
|
|
69
|
+
**PhysicalParameterObject** - a PhysicalParameterBlock object.}""",
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
CONFIG.declare(
|
|
73
|
+
"property_package_args",
|
|
74
|
+
ConfigBlock(
|
|
75
|
+
implicit=True,
|
|
76
|
+
description="Arguments to use for constructing property packages",
|
|
77
|
+
doc="""A ConfigBlock with arguments to be passed to a property block(s)
|
|
78
|
+
and used when constructing these,
|
|
79
|
+
**default** - None.
|
|
80
|
+
**Valid values:** {
|
|
81
|
+
see property package for documentation.}""",
|
|
82
|
+
),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def build(self):
|
|
86
|
+
# build always starts by calling super().build()
|
|
87
|
+
# This triggers a lot of boilerplate in the background for you
|
|
88
|
+
super().build()
|
|
89
|
+
|
|
90
|
+
# This creates blank scaling factors, which are populated later
|
|
91
|
+
self.scaling_factor = Suffix(direction=Suffix.EXPORT)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# Add state blocks for inlet, outlet, and waste
|
|
95
|
+
# These include the state variables and any other properties on demand
|
|
96
|
+
# Add inlet block
|
|
97
|
+
tmp_dict = dict(**self.config.property_package_args)
|
|
98
|
+
tmp_dict["parameters"] = self.config.property_package
|
|
99
|
+
#tmp_dict["defined_state"] = True # inlet block is an inlet
|
|
100
|
+
|
|
101
|
+
# Add outlet
|
|
102
|
+
tmp_dict["defined_state"] = False # outlet is not an inlet
|
|
103
|
+
self.properties_out = self.config.property_package.state_block_class(
|
|
104
|
+
self.flowsheet().config.time,
|
|
105
|
+
doc="Material properties of outlet",
|
|
106
|
+
**tmp_dict
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Add ports - oftentimes users interact with these rather than the state blocks
|
|
110
|
+
|
|
111
|
+
self.add_port(name="outlet", block=self.properties_out)
|
|
112
|
+
|
|
113
|
+
# Add variable for efficiency
|
|
114
|
+
self.efficiency = Var(
|
|
115
|
+
initialize=1.0,
|
|
116
|
+
doc="Efficiency",
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Add variable for flow rate of water m3/s
|
|
120
|
+
self.flow_rate = Var(self.flowsheet().config.time,
|
|
121
|
+
initialize=1.0, units = pyunits.m**3/pyunits.s,
|
|
122
|
+
doc="Flow rate of water",
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Add variable for Static Head in meters
|
|
126
|
+
self.static_head = Var(
|
|
127
|
+
initialize=1.0, units = pyunits.m,
|
|
128
|
+
doc="Effective Head or height of the water column",
|
|
129
|
+
)
|
|
130
|
+
# Add variable for Cp which is density of water in kg/m3
|
|
131
|
+
self.Cp= 1000
|
|
132
|
+
# Add variable for Cg which is gravitational acceleration in m/s2
|
|
133
|
+
self.Cg= 9.81
|
|
134
|
+
|
|
135
|
+
# Add constraints
|
|
136
|
+
@self.Constraint(
|
|
137
|
+
self.flowsheet().time,
|
|
138
|
+
doc="Power usage",
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def eq_power_balance(b, t):
|
|
142
|
+
return (
|
|
143
|
+
(self.flow_rate[t] * self.Cg * self.Cp * self.efficiency * self.static_head == b.properties_out[t].power)
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def calculate_scaling_factors(self):
|
|
148
|
+
super().calculate_scaling_factors()
|
|
149
|
+
|
|
150
|
+
def initialize(blk, *args, **kwargs):
|
|
151
|
+
# Just propagate the power from inlet to outlet, good simple method of initialization
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
def _get_stream_table_contents(self, time_point=0):
|
|
155
|
+
"""
|
|
156
|
+
Assume unit has standard configuration of 1 inlet and 1 outlet.
|
|
157
|
+
|
|
158
|
+
Developers should overload this as appropriate.
|
|
159
|
+
"""
|
|
160
|
+
try:
|
|
161
|
+
return create_stream_table_dataframe(
|
|
162
|
+
{"Outlet": self.outlet}, time_point=time_point
|
|
163
|
+
)
|
|
164
|
+
except AttributeError:
|
|
165
|
+
raise ConfigurationError(
|
|
166
|
+
f"Unit model {self.name} does not have the standard Port "
|
|
167
|
+
f"names (inlet and outlet). Please contact the unit model "
|
|
168
|
+
f"developer to develop a unit specific stream table."
|
|
169
|
+
)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Import Pyomo libraries
|
|
2
|
+
from pyomo.environ import (
|
|
3
|
+
Var,
|
|
4
|
+
Suffix,
|
|
5
|
+
units as pyunits,
|
|
6
|
+
)
|
|
7
|
+
from pyomo.common.config import ConfigBlock, ConfigValue, In
|
|
8
|
+
|
|
9
|
+
# Import IDAES cores
|
|
10
|
+
from idaes.core import (
|
|
11
|
+
declare_process_block_class,
|
|
12
|
+
UnitModelBlockData,
|
|
13
|
+
useDefault,
|
|
14
|
+
)
|
|
15
|
+
from idaes.core.util.config import is_physical_parameter_block
|
|
16
|
+
import idaes.core.util.scaling as iscale
|
|
17
|
+
import idaes.logger as idaeslog
|
|
18
|
+
|
|
19
|
+
# Set up logger
|
|
20
|
+
_log = idaeslog.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# When using this file the name "Link" is what is imported
|
|
24
|
+
@declare_process_block_class("Link")
|
|
25
|
+
class LinkData(UnitModelBlockData):
|
|
26
|
+
"""
|
|
27
|
+
Zero order Link model
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# CONFIG are options for the unit model, this simple model only has the mandatory config options
|
|
31
|
+
CONFIG = ConfigBlock()
|
|
32
|
+
|
|
33
|
+
CONFIG.declare(
|
|
34
|
+
"dynamic",
|
|
35
|
+
ConfigValue(
|
|
36
|
+
domain=In([False]),
|
|
37
|
+
default=False,
|
|
38
|
+
description="Dynamic model flag - must be False",
|
|
39
|
+
doc="""Indicates whether this model will be dynamic or not,
|
|
40
|
+
**default** = False. The Bus unit does not support dynamic
|
|
41
|
+
behavior, thus this must be False.""",
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
CONFIG.declare(
|
|
45
|
+
"has_holdup",
|
|
46
|
+
ConfigValue(
|
|
47
|
+
default=False,
|
|
48
|
+
domain=In([False]),
|
|
49
|
+
description="Holdup construction flag - must be False",
|
|
50
|
+
doc="""Indicates whether holdup terms should be constructed or not.
|
|
51
|
+
**default** - False. The Bus unit does not have defined volume, thus
|
|
52
|
+
this must be False.""",
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
CONFIG.declare(
|
|
56
|
+
"property_package",
|
|
57
|
+
ConfigValue(
|
|
58
|
+
default=useDefault,
|
|
59
|
+
domain=is_physical_parameter_block,
|
|
60
|
+
description="Property package to use for control volume",
|
|
61
|
+
doc="""Property parameter object used to define property calculations,
|
|
62
|
+
**default** - useDefault.
|
|
63
|
+
**Valid values:** {
|
|
64
|
+
**useDefault** - use default package from parent model or flowsheet,
|
|
65
|
+
**PhysicalParameterObject** - a PhysicalParameterBlock object.}""",
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
CONFIG.declare(
|
|
69
|
+
"property_package_args",
|
|
70
|
+
ConfigBlock(
|
|
71
|
+
implicit=True,
|
|
72
|
+
description="Arguments to use for constructing property packages",
|
|
73
|
+
doc="""A ConfigBlock with arguments to be passed to a property block(s)
|
|
74
|
+
and used when constructing these,
|
|
75
|
+
**default** - None.
|
|
76
|
+
**Valid values:** {
|
|
77
|
+
see property package for documentation.}""",
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
def build(self):
|
|
82
|
+
# build always starts by calling super().build()
|
|
83
|
+
# This triggers a lot of boilerplate in the background for you
|
|
84
|
+
super().build()
|
|
85
|
+
|
|
86
|
+
# This creates blank scaling factors, which are populated later
|
|
87
|
+
self.scaling_factor = Suffix(direction=Suffix.EXPORT)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# Add state blocks for inlet, outlet, and waste
|
|
91
|
+
# These include the state variables and any other properties on demand
|
|
92
|
+
# Add inlet block
|
|
93
|
+
tmp_dict = dict(**self.config.property_package_args)
|
|
94
|
+
tmp_dict["parameters"] = self.config.property_package
|
|
95
|
+
tmp_dict["defined_state"] = True # inlet block is an inlet
|
|
96
|
+
self.properties_in = self.config.property_package.state_block_class(
|
|
97
|
+
self.flowsheet().config.time, doc="Material properties of inlet", **tmp_dict
|
|
98
|
+
)
|
|
99
|
+
# Add outlet and waste block
|
|
100
|
+
tmp_dict["defined_state"] = False # outlet and waste block is not an inlet
|
|
101
|
+
self.properties_out = self.config.property_package.state_block_class(
|
|
102
|
+
self.flowsheet().config.time,
|
|
103
|
+
doc="Material properties of outlet",
|
|
104
|
+
**tmp_dict
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Add ports - oftentimes users interact with these rather than the state blocks
|
|
108
|
+
self.add_port(name="inlet", block=self.properties_in)
|
|
109
|
+
self.add_port(name="outlet", block=self.properties_out)
|
|
110
|
+
|
|
111
|
+
# Add variable for efficiency
|
|
112
|
+
self.efficiency = Var(self.flowsheet().config.time,
|
|
113
|
+
initialize=1.0,
|
|
114
|
+
doc="Efficiency of the bus",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Add constraints
|
|
118
|
+
# Usually unit models use a control volume to do the mass, energy, and momentum
|
|
119
|
+
# balances, however, they will be explicitly written out in this example
|
|
120
|
+
@self.Constraint(
|
|
121
|
+
self.flowsheet().time,
|
|
122
|
+
doc="Power usage",
|
|
123
|
+
)
|
|
124
|
+
def eq_power_balance(b, t):
|
|
125
|
+
return (
|
|
126
|
+
b.properties_in[t].power * self.efficiency[t] == b.properties_out[t].power
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def calculate_scaling_factors(self):
|
|
131
|
+
super().calculate_scaling_factors()
|
|
132
|
+
|
|
133
|
+
def initialize(blk, *args, **kwargs):
|
|
134
|
+
# Just propagate the power from inlet to outlet, good simple method of initialization
|
|
135
|
+
for i in blk.properties_in.index_set():
|
|
136
|
+
if not blk.properties_out[i].power.fixed:
|
|
137
|
+
blk.properties_out[i].power = blk.properties_in[i].power.value
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Import Pyomo libraries
|
|
2
|
+
from pyomo.environ import (
|
|
3
|
+
Var,
|
|
4
|
+
Suffix,
|
|
5
|
+
units as pyunits,
|
|
6
|
+
)
|
|
7
|
+
from pyomo.common.config import ConfigBlock, ConfigValue, In
|
|
8
|
+
from idaes.core.util.tables import create_stream_table_dataframe
|
|
9
|
+
from idaes.core.util.exceptions import ConfigurationError
|
|
10
|
+
# Import IDAES cores
|
|
11
|
+
from idaes.core import (
|
|
12
|
+
declare_process_block_class,
|
|
13
|
+
UnitModelBlockData,
|
|
14
|
+
useDefault,
|
|
15
|
+
)
|
|
16
|
+
from idaes.core.util.config import is_physical_parameter_block
|
|
17
|
+
import idaes.core.util.scaling as iscale
|
|
18
|
+
import idaes.logger as idaeslog
|
|
19
|
+
|
|
20
|
+
# Set up logger
|
|
21
|
+
_log = idaeslog.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# When using this file the name "Load" is what is imported
|
|
25
|
+
@declare_process_block_class("Load")
|
|
26
|
+
class loadData(UnitModelBlockData):
|
|
27
|
+
"""
|
|
28
|
+
Zero order Load model
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# CONFIG are options for the unit model, this simple model only has the mandatory config options
|
|
32
|
+
CONFIG = ConfigBlock()
|
|
33
|
+
|
|
34
|
+
CONFIG.declare(
|
|
35
|
+
"dynamic",
|
|
36
|
+
ConfigValue(
|
|
37
|
+
domain=In([False]),
|
|
38
|
+
default=False,
|
|
39
|
+
description="Dynamic model flag - must be False",
|
|
40
|
+
doc="""Indicates whether this model will be dynamic or not,
|
|
41
|
+
**default** = False. The Bus unit does not support dynamic
|
|
42
|
+
behavior, thus this must be False.""",
|
|
43
|
+
),
|
|
44
|
+
)
|
|
45
|
+
CONFIG.declare(
|
|
46
|
+
"has_holdup",
|
|
47
|
+
ConfigValue(
|
|
48
|
+
default=False,
|
|
49
|
+
domain=In([False]),
|
|
50
|
+
description="Holdup construction flag - must be False",
|
|
51
|
+
doc="""Indicates whether holdup terms should be constructed or not.
|
|
52
|
+
**default** - False. The Bus unit does not have defined volume, thus
|
|
53
|
+
this must be False.""",
|
|
54
|
+
),
|
|
55
|
+
)
|
|
56
|
+
CONFIG.declare(
|
|
57
|
+
"property_package",
|
|
58
|
+
ConfigValue(
|
|
59
|
+
default=useDefault,
|
|
60
|
+
domain=is_physical_parameter_block,
|
|
61
|
+
description="Property package to use for control volume",
|
|
62
|
+
doc="""Property parameter object used to define property calculations,
|
|
63
|
+
**default** - useDefault.
|
|
64
|
+
**Valid values:** {
|
|
65
|
+
**useDefault** - use default package from parent model or flowsheet,
|
|
66
|
+
**PhysicalParameterObject** - a PhysicalParameterBlock object.}""",
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
CONFIG.declare(
|
|
70
|
+
"property_package_args",
|
|
71
|
+
ConfigBlock(
|
|
72
|
+
implicit=True,
|
|
73
|
+
description="Arguments to use for constructing property packages",
|
|
74
|
+
doc="""A ConfigBlock with arguments to be passed to a property block(s)
|
|
75
|
+
and used when constructing these,
|
|
76
|
+
**default** - None.
|
|
77
|
+
**Valid values:** {
|
|
78
|
+
see property package for documentation.}""",
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def build(self):
|
|
83
|
+
# build always starts by calling super().build()
|
|
84
|
+
# This triggers a lot of boilerplate in the background for you
|
|
85
|
+
super().build()
|
|
86
|
+
|
|
87
|
+
# This creates blank scaling factors, which are populated later
|
|
88
|
+
self.scaling_factor = Suffix(direction=Suffix.EXPORT)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# Add state blocks for inlet, outlet, and waste
|
|
92
|
+
# These include the state variables and any other properties on demand
|
|
93
|
+
# Add inlet block
|
|
94
|
+
tmp_dict = dict(**self.config.property_package_args)
|
|
95
|
+
tmp_dict["parameters"] = self.config.property_package
|
|
96
|
+
tmp_dict["defined_state"] = True # inlet block is an inlet
|
|
97
|
+
self.properties_in = self.config.property_package.state_block_class(
|
|
98
|
+
self.flowsheet().config.time, doc="Material properties of inlet", **tmp_dict
|
|
99
|
+
)
|
|
100
|
+
# Add outlet and waste block
|
|
101
|
+
tmp_dict["defined_state"] = False # outlet and waste block is not an inlet
|
|
102
|
+
self.properties_out = self.config.property_package.state_block_class(
|
|
103
|
+
self.flowsheet().config.time,
|
|
104
|
+
doc="Material properties of outlet",
|
|
105
|
+
**tmp_dict
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Add ports - oftentimes users interact with these rather than the state blocks
|
|
109
|
+
self.add_port(name="outlet", block=self.properties_out)
|
|
110
|
+
|
|
111
|
+
# Add variables
|
|
112
|
+
self.in_power = Var(self.flowsheet().config.time,
|
|
113
|
+
initialize=1.0,
|
|
114
|
+
doc="Load voltage",
|
|
115
|
+
units = pyunits.W
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Add constraints
|
|
119
|
+
# Usually unit models use a control volume to do the mass, energy, and momentum
|
|
120
|
+
# balances, however, they will be explicitly written out in this example
|
|
121
|
+
@self.Constraint(
|
|
122
|
+
self.flowsheet().time,
|
|
123
|
+
doc="Power usage",
|
|
124
|
+
)
|
|
125
|
+
def eq_power_in_balance(b, t):
|
|
126
|
+
return (
|
|
127
|
+
b.properties_out[t].power == self.in_power[t] * -1
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def calculate_scaling_factors(self):
|
|
132
|
+
super().calculate_scaling_factors()
|
|
133
|
+
|
|
134
|
+
def initialize(blk, *args, **kwargs):
|
|
135
|
+
# Just propagate the power from inlet to outlet, good simple method of initialization
|
|
136
|
+
for i in blk.properties_in.index_set():
|
|
137
|
+
if not blk.properties_out[i].power.fixed:
|
|
138
|
+
blk.properties_out[i].power = blk.properties_in[i].power.value
|
|
139
|
+
|
|
140
|
+
def _get_stream_table_contents(self, time_point=0):
|
|
141
|
+
"""
|
|
142
|
+
Assume unit has standard configuration of 1 inlet and 1 outlet.
|
|
143
|
+
|
|
144
|
+
Developers should overload this as appropriate.
|
|
145
|
+
"""
|
|
146
|
+
try:
|
|
147
|
+
return create_stream_table_dataframe(
|
|
148
|
+
{"outlet": self.outlet}, time_point=time_point
|
|
149
|
+
)
|
|
150
|
+
except AttributeError:
|
|
151
|
+
raise ConfigurationError(
|
|
152
|
+
f"Unit model {self.name} does not have the standard Port "
|
|
153
|
+
f"names (inlet and outlet). Please contact the unit model "
|
|
154
|
+
f"developer to develop a unit specific stream table."
|
|
155
|
+
)
|