94 lines
3.7 KiB
Python
94 lines
3.7 KiB
Python
from math import sqrt, log
|
|
import math
|
|
|
|
from helix.constants.global_constants import parapet_coefficients, parapet_factor_max
|
|
from numpy import array
|
|
from numpy.ma import maximum
|
|
|
|
from helix.constants.panel_type import PanelType
|
|
|
|
|
|
class PressureCoefficientCalculator(object):
|
|
def __init__(self, user_values):
|
|
self.values = user_values
|
|
self.system_constants = self.values.system_type().system_constants()
|
|
self.module_constants = self.values.module_system_constants()
|
|
|
|
def c_p_matrix(self, L_B):
|
|
parapet = self.parapet_factor()
|
|
return self.compute_c_p_matrix(L_B, parapet)
|
|
|
|
def L_B(self):
|
|
""" Building scaling factor """
|
|
height = max(15, self.values.building_height())
|
|
|
|
length = self.values.building_length()
|
|
width = self.values.building_width()
|
|
|
|
longest_side = max(width, length)
|
|
|
|
return min(height, 0.4 * sqrt(height * max(1, longest_side)))
|
|
|
|
def minimum_array_size(self, L_B):
|
|
panel_area = self.module_constants.panel_area
|
|
module_count = self.system_constants.module_count
|
|
minimum_array_size = []
|
|
for minimum_A_n in self.minimum_A_n(L_B):
|
|
if minimum_A_n is None:
|
|
value = 6
|
|
else:
|
|
value = int(math.ceil((minimum_A_n * L_B ** 2) / (panel_area * 1000) / module_count))
|
|
minimum_array_size.append(value)
|
|
return minimum_array_size
|
|
|
|
# Normalized area, scales the tributary area by the building scaling factor and panel area
|
|
def A_n(self, L_B):
|
|
return self.module_constants.tributary_area * (self.module_constants.panel_area * 1000. / L_B ** 2)
|
|
|
|
def compute_c_p_matrix(self, L_B, parapet):
|
|
A_n = self.A_n(L_B)
|
|
wind_zones = self.system_constants.wind_zones
|
|
return array([self.c_p_row(A_n, wind_zone, parapet) for wind_zone in wind_zones])
|
|
|
|
def c_p_row(self, A_n_row, wind_zone, parapet_factor):
|
|
c_p_lower_bound = self.module_constants.c_p_lower_bound()
|
|
|
|
if wind_zone == self.system_constants.wind_zones[-1]:
|
|
return c_p_lower_bound
|
|
computed_row = []
|
|
for index, A_n in enumerate(A_n_row):
|
|
edge_factor = self.module_constants.edge_factor(wind_zone, PanelType.from_index(index))
|
|
computed_row.append(self.c_p(A_n, wind_zone, parapet_factor, edge_factor))
|
|
|
|
return maximum(array(computed_row), c_p_lower_bound)
|
|
|
|
def c_p(self, A_n, wind_zone, parapet_factor, edge_factor):
|
|
c0, c1 = self.module_constants.c_p_constants(A_n, wind_zone)
|
|
return max(0., c0 * log(A_n) + c1) * parapet_factor * edge_factor
|
|
|
|
def parapet_factor(self):
|
|
height = max(15, self.values.building_height())
|
|
parapet_height = max(0, self.values.building_parapet_height())
|
|
|
|
factor = parapet_height / height
|
|
c0, c1 = parapet_coefficients
|
|
return min(parapet_factor_max, c0 + c1 * factor)
|
|
|
|
def ideal_subarray_average_uplift_c_p(self, L_B):
|
|
c_p_matrix = self.compute_c_p_matrix(L_B, 1)
|
|
return [self.module_constants.weighted_average_c_p(c, n, e, m) for c, n, e, m in c_p_matrix]
|
|
|
|
def minimum_A_n(self, L_B):
|
|
uplift_c_p = self.ideal_subarray_average_uplift_c_p(L_B)
|
|
minimum_A_n = []
|
|
for idx, wind_zone in enumerate(self.system_constants.wind_zones):
|
|
wind_zone_uplift = uplift_c_p[idx]
|
|
coefficients = self.module_constants.minimum_a_n_coefficients(wind_zone_uplift, wind_zone)
|
|
if not coefficients:
|
|
minimum_A_n.append(None)
|
|
continue
|
|
|
|
value = math.exp((coefficients[0] - wind_zone_uplift) / coefficients[1])
|
|
minimum_A_n.append(value)
|
|
return minimum_A_n
|