Coverage for teaser/logic/buildingobjects/calculation/ibpsa.py: 97%

30 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-04-29 16:01 +0000

1"""This module includes IBPSA calculation class.""" 

2 

3import os 

4import pandas as pd 

5import teaser.logic.utilities as utilities 

6 

7 

8class IBPSA(object): 

9 """Class to calculate parameters for AixLib output. 

10 

11 This class holds functions to sort and partly rewrite zone and building 

12 attributes specific for IBPSA simulation. This includes the export of 

13 boundary conditions. 

14 

15 Parameters 

16 ---------- 

17 parent: Building() 

18 The parent class of this object, the Building the attributes are 

19 calculated for. (default: None) 

20 

21 Attributes 

22 ---------- 

23 file_internal_gains : str 

24 Filename for internal gains file 

25 version : dict 

26 Dictionary with supported libraries and their version numbers 

27 consider_heat_capacity : bool 

28 decides whether air capacity is considered or not for all thermal 

29 zones in the building 

30 

31 

32 """ 

33 

34 def __init__(self, parent): 

35 """Construct IBPSA.""" 

36 self.parent = parent 

37 self.file_internal_gains = "InternalGains_" + self.parent.name + ".mat" 

38 self.version = { 

39 "AixLib": "2.1.1", 

40 "Buildings": "11.0.0", 

41 "BuildingSystems": "2.0.0-beta2", 

42 "IDEAS": "3.0.0", 

43 } 

44 self.consider_heat_capacity = True 

45 

46 def modelica_gains_boundary(self, zone, path=None): 

47 """creates .mat file for internal gains boundary conditions 

48 

49 This function creates a matfile (-v4) for building internal gains 

50 boundary conditions. It collects internal gain profiles of a specific 

51 zones and stores them into one file. It also calculates the internal 

52 gains from relative presence and values for heat output into W for 

53 direct usage in Annex models. 

54 

55 Only person (convective and radiative) and machines (convective) are 

56 used in the simple Annex 60 examples. 

57 

58 1. Column : time step 

59 2 Column : profile_persons, radiative 

60 3 Column : profile_persons, convective 

61 4 Column : profile_machines, convective 

62 

63 Notes 

64 ----- 

65 When time line is created, we need to add a 0 to first element of 

66 all boundaries. This is due to to expected format in Modelica. 

67 

68 Parameters 

69 ---------- 

70 zone : ThermalZone() 

71 TEASER instance of ThermalZone. As IBPSA computes single models 

72 for single zones, we need to generate individual files for zones 

73 and internal gains 

74 path : str 

75 optional path, when matfile is exported separately 

76 

77 """ 

78 if path is None: 

79 path = utilities.get_default_path() 

80 else: 

81 pass 

82 

83 utilities.create_path(path) 

84 path = os.path.join(path, self.file_internal_gains) 

85 

86 export = pd.DataFrame( 

87 index=pd.date_range("2019-01-01 00:00:00", periods=8760, freq="h") 

88 .to_series() 

89 .dt.strftime("%m-%d %H:%M:%S") 

90 ) 

91 

92 export["person_rad_{}".format(zone.name)] = ( 

93 zone.use_conditions.schedules["persons_profile"] 

94 * (1 - zone.use_conditions.ratio_conv_rad_persons) 

95 * zone.use_conditions.fixed_heat_flow_rate_persons 

96 * zone.use_conditions.persons 

97 * zone.area 

98 ) 

99 export["person_conv_{}".format(zone.name)] = ( 

100 zone.use_conditions.schedules["persons_profile"] 

101 * zone.use_conditions.ratio_conv_rad_persons 

102 * zone.use_conditions.fixed_heat_flow_rate_persons 

103 * zone.use_conditions.persons 

104 * zone.area 

105 ) 

106 export["machines_conv_{}".format(zone.name)] = ( 

107 zone.use_conditions.schedules["machines_profile"] 

108 * zone.use_conditions.ratio_conv_rad_machines 

109 * zone.use_conditions.machines 

110 * zone.area 

111 ) 

112 

113 export.index = [(i + 1) * 3600 for i in range(8760)] 

114 self._delete_file(path=path) 

115 with open(path, "a") as f: 

116 f.write("#1\n") 

117 # The size of the dataset is always 4 columns as each thermal zone has its own data file. 

118 f.write("double Internals(8761, 4)\n") 

119 # write the first row with t=0 

120 f.write("0\t{}".format(export.iloc[:1, :].to_csv(sep="\t", header=False, index=False))) 

121 export.to_csv(f, sep="\t", header=False, index_label=False) 

122 

123 def _delete_file(self, path): 

124 """Delete a file before new information is written to it. 

125 

126 If a building with the exact name and project name is generated, we need to make 

127 sure to delete the old information in the text files. This helper function is a 

128 wrapper to delete a file with given filepath. 

129 

130 Parameters: 

131 ----------- 

132 path : str 

133 Absolute path to the file to be deleted. 

134 

135 """ 

136 try: 

137 os.remove(path) 

138 except OSError: 

139 pass