Files
old-krovovi-kalkulator/helix/calculators/pressure_coefficient_calculator.py
2017-11-07 09:23:57 +01:00

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