Coverage for backend/idaes_service/solver/custom/custom_compressor.py: 100%

26 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-11-06 23:27 +0000

1# Import Pyomo libraries 

2from pyomo.environ import ( 

3 Var, 

4 Suffix, 

5 units as pyunits, 

6) 

7from pyomo.common.config import ConfigBlock, ConfigValue, In 

8from idaes.core.util.tables import create_stream_table_dataframe 

9from idaes.core.util.exceptions import ConfigurationError 

10# Import IDAES cores 

11from idaes.core import ( 

12 declare_process_block_class, 

13 UnitModelBlockData, 

14 useDefault, 

15) 

16from idaes.core.util.config import is_physical_parameter_block 

17import idaes.core.util.scaling as iscale 

18import idaes.logger as idaeslog 

19 

20from ..custom.updated_pressure_changer import ( 

21 

22 CompressorData, 

23) 

24 

25 

26 

27 

28# When using this file the name "CustomCompressor" is what is imported 

29@declare_process_block_class("CustomCompressor") 

30class CustomCompressorData(CompressorData): 

31 """ 

32 Zero order Load model 

33 """ 

34 

35 # CONFIG are options for the unit model, this simple model only has the mandatory config options 

36 CONFIG = CompressorData.CONFIG() 

37 

38 CONFIG.declare( 

39 "power_property_package", 

40 ConfigValue( 

41 default=useDefault, 

42 domain=is_physical_parameter_block, 

43 description="Property package to use for power", 

44 doc="""Power Property parameter object used to define power calculations, 

45 **default** - useDefault. 

46 **Valid values:** { 

47 **useDefault** - use default package from parent model or flowsheet, 

48 **PhysicalParameterObject** - a PhysicalParameterBlock object.}""", 

49 ), 

50 ) 

51 CONFIG.declare( 

52 "power_property_package_args", 

53 ConfigBlock( 

54 implicit=True, 

55 description="Arguments to use for constructing power property packages", 

56 doc="""A ConfigBlock with arguments to be passed to a property block(s) 

57 and used when constructing these, 

58 **default** - None.  

59 **Valid values:** { 

60 see property package for documentation.}""", 

61 ), 

62 ) 

63 

64 def build(self): 

65 # build always starts by calling super().build() 

66 # This triggers a lot of boilerplate in the background for you 

67 super().build() 

68 

69 # This creates blank scaling factors, which are populated later 

70 self.scaling_factor = Suffix(direction=Suffix.EXPORT) 

71 

72 

73 # Add state blocks for inlet, outlet, and waste 

74 # These include the state variables and any other properties on demand 

75 

76 tmp_dict = dict(**self.config.property_package_args) 

77 tmp_dict["parameters"] = self.config.property_package 

78 tmp_dict["defined_state"] = True # inlet block is an inlet 

79 # Add inlet block 

80 # self.properties_in = self.config.property_package.state_block_class( 

81 # self.flowsheet().config.time, doc="Material properties of inlet", **tmp_dict 

82 # ) 

83 

84 

85 # Add outlet and waste block 

86 tmp_dict["defined_state"] = False # outlet and waste block is not an inlet 

87 self.power_properties_out = self.config.power_property_package.state_block_class( 

88 self.flowsheet().config.time, 

89 doc="Material properties of outlet", 

90 **tmp_dict 

91 ) 

92 

93 # Add ports - oftentimes users interact with these rather than the state blocks 

94 self.add_port(name="power_outlet", block=self.power_properties_out) 

95 

96 # Add constraints 

97 # Usually unit models use a control volume to do the mass, energy, and momentum 

98 # balances, however, they will be explicitly written out in this example 

99 @self.Constraint( 

100 self.flowsheet().time, 

101 doc="Power out", 

102 ) 

103 def eq_power_out(b, t): 

104 return ( 

105 self.power_properties_out[t].power == self.work_mechanical[t] * -1 

106 ) 

107