mabuseif commited on
Commit
dac656b
·
verified ·
1 Parent(s): e47065b

Update data/calculation.py

Browse files
Files changed (1) hide show
  1. data/calculation.py +27 -8
data/calculation.py CHANGED
@@ -13,6 +13,7 @@ from data.material_library import Construction, GlazingMaterial, DoorMaterial
13
  from data.internal_loads import PEOPLE_ACTIVITY_LEVELS, DIVERSITY_FACTORS, LIGHTING_FIXTURE_TYPES, EQUIPMENT_HEAT_GAINS, VENTILATION_RATES, INFILTRATION_SETTINGS
14
  import scipy.linalg as linalg
15
  from datetime import datetime
 
16
 
17
  class ComponentType(Enum):
18
  WALL = "Wall"
@@ -137,8 +138,6 @@ class TFMCalculations:
137
  @staticmethod
138
  def get_adaptive_comfort_temp(outdoor_temp: float) -> float:
139
  """Calculate adaptive comfort temperature per ASHRAE 55."""
140
- # Simplified ASHRAE 55 adaptive model: T_comf = 0.31 * T_out + 17.8
141
- # Valid for 10°C ≤ T_out ≤ 33.5°C
142
  if 10 <= outdoor_temp <= 33.5:
143
  return 0.31 * outdoor_temp + 17.8
144
  return 24.0 # Default to standard setpoint if outside range
@@ -171,7 +170,6 @@ class TFMCalculations:
171
  def get_indoor_conditions(indoor_conditions: Dict, hour: int, outdoor_temp: float) -> Dict:
172
  """Determine indoor conditions based on user settings."""
173
  if indoor_conditions["type"] == "Fixed":
174
- # Select cooling or heating setpoint based on outdoor temperature
175
  mode = "none" if abs(outdoor_temp - 18) < 0.01 else "cooling" if outdoor_temp > 18 else "heating"
176
  if mode == "cooling":
177
  return {
@@ -183,7 +181,7 @@ class TFMCalculations:
183
  "temperature": indoor_conditions.get("heating_setpoint", {}).get("temperature", 22.0),
184
  "rh": indoor_conditions.get("heating_setpoint", {}).get("rh", 50.0)
185
  }
186
- else: # mode == "none"
187
  return {"temperature": 24.0, "rh": 50.0}
188
  elif indoor_conditions["type"] == "Time-varying":
189
  schedule = indoor_conditions.get("schedule", [])
@@ -200,7 +198,7 @@ class TFMCalculations:
200
  def calculate_tfm_loads(components: Dict, hourly_data: List[Dict], indoor_conditions: Dict, internal_loads: Dict, building_info: Dict, sim_period: Dict, hvac_settings: Dict) -> List[Dict]:
201
  """Calculate TFM loads for heating and cooling with user-defined filters and temperature threshold."""
202
  filtered_data = TFMCalculations.filter_hourly_data(hourly_data, sim_period, building_info)
203
- loads = []
204
  building_orientation = building_info.get("orientation_angle", 0.0)
205
  operating_periods = hvac_settings.get("operating_hours", [{"start": 8, "end": 18}])
206
  area = building_info.get("floor_area", 100.0)
@@ -243,14 +241,15 @@ class TFMCalculations:
243
  # Calculate total loads, subtracting internal load for heating
244
  total_cooling = conduction_cooling + solar + internal + ventilation_cooling + infiltration_cooling
245
  total_heating = max(conduction_heating + ventilation_heating + infiltration_heating - internal, 0)
246
- # Enforce mutual exclusivity
247
  if mode == "cooling":
248
  total_heating = 0
249
  elif mode == "heating":
250
  total_cooling = 0
251
- loads.append({
252
  "hour": hour,
253
  "month": hour_data["month"],
 
254
  "conduction_cooling": conduction_cooling,
255
  "conduction_heating": conduction_heating,
256
  "solar": solar,
@@ -262,4 +261,24 @@ class TFMCalculations:
262
  "total_cooling": total_cooling,
263
  "total_heating": total_heating
264
  })
265
- return loads
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  from data.internal_loads import PEOPLE_ACTIVITY_LEVELS, DIVERSITY_FACTORS, LIGHTING_FIXTURE_TYPES, EQUIPMENT_HEAT_GAINS, VENTILATION_RATES, INFILTRATION_SETTINGS
14
  import scipy.linalg as linalg
15
  from datetime import datetime
16
+ from collections import defaultdict
17
 
18
  class ComponentType(Enum):
19
  WALL = "Wall"
 
138
  @staticmethod
139
  def get_adaptive_comfort_temp(outdoor_temp: float) -> float:
140
  """Calculate adaptive comfort temperature per ASHRAE 55."""
 
 
141
  if 10 <= outdoor_temp <= 33.5:
142
  return 0.31 * outdoor_temp + 17.8
143
  return 24.0 # Default to standard setpoint if outside range
 
170
  def get_indoor_conditions(indoor_conditions: Dict, hour: int, outdoor_temp: float) -> Dict:
171
  """Determine indoor conditions based on user settings."""
172
  if indoor_conditions["type"] == "Fixed":
 
173
  mode = "none" if abs(outdoor_temp - 18) < 0.01 else "cooling" if outdoor_temp > 18 else "heating"
174
  if mode == "cooling":
175
  return {
 
181
  "temperature": indoor_conditions.get("heating_setpoint", {}).get("temperature", 22.0),
182
  "rh": indoor_conditions.get("heating_setpoint", {}).get("rh", 50.0)
183
  }
184
+ else:
185
  return {"temperature": 24.0, "rh": 50.0}
186
  elif indoor_conditions["type"] == "Time-varying":
187
  schedule = indoor_conditions.get("schedule", [])
 
198
  def calculate_tfm_loads(components: Dict, hourly_data: List[Dict], indoor_conditions: Dict, internal_loads: Dict, building_info: Dict, sim_period: Dict, hvac_settings: Dict) -> List[Dict]:
199
  """Calculate TFM loads for heating and cooling with user-defined filters and temperature threshold."""
200
  filtered_data = TFMCalculations.filter_hourly_data(hourly_data, sim_period, building_info)
201
+ temp_loads = []
202
  building_orientation = building_info.get("orientation_angle", 0.0)
203
  operating_periods = hvac_settings.get("operating_hours", [{"start": 8, "end": 18}])
204
  area = building_info.get("floor_area", 100.0)
 
241
  # Calculate total loads, subtracting internal load for heating
242
  total_cooling = conduction_cooling + solar + internal + ventilation_cooling + infiltration_cooling
243
  total_heating = max(conduction_heating + ventilation_heating + infiltration_heating - internal, 0)
244
+ # Enforce mutual exclusivity within hour
245
  if mode == "cooling":
246
  total_heating = 0
247
  elif mode == "heating":
248
  total_cooling = 0
249
+ temp_loads.append({
250
  "hour": hour,
251
  "month": hour_data["month"],
252
+ "day": hour_data["day"],
253
  "conduction_cooling": conduction_cooling,
254
  "conduction_heating": conduction_heating,
255
  "solar": solar,
 
261
  "total_cooling": total_cooling,
262
  "total_heating": total_heating
263
  })
264
+ # Group loads by day and apply daily control
265
+ loads_by_day = defaultdict(list)
266
+ for load in temp_loads:
267
+ day_key = (load["month"], load["day"])
268
+ loads_by_day[day_key].append(load)
269
+ final_loads = []
270
+ for day_key, day_loads in loads_by_day.items():
271
+ # Count hours with non-zero cooling and heating loads
272
+ cooling_hours = sum(1 for load in day_loads if load["total_cooling"] > 0)
273
+ heating_hours = sum(1 for load in day_loads if load["total_heating"] > 0)
274
+ # Apply daily control
275
+ for load in day_loads:
276
+ if cooling_hours > heating_hours:
277
+ load["total_heating"] = 0 # Keep cooling components, zero heating total
278
+ elif heating_hours > cooling_hours:
279
+ load["total_cooling"] = 0 # Keep heating components, zero cooling total
280
+ else: # Equal hours
281
+ load["total_cooling"] = 0
282
+ load["total_heating"] = 0 # Zero both totals, keep components
283
+ final_loads.append(load)
284
+ return final_loads