Kildekode for tilstand

import math
import numpy
import copy


[dokumentasjon]class Tilstand(object): """Objekt med informasjon om lasttilstand fra lastfaktoranalyse. Lagres i masteobjekt via metoden mast.lagre_lasttilfelle(lasttilfelle) """
[dokumentasjon] def __init__(self, mast, i, lastsituasjon, vindretning, type, F=None, R=None, D=None, G=0, L=0, T=0, S=0, V=0, iterasjon=0): """Initialiserer :class:`Tilstand`-objekt. Alternativer for ``vindretning``: - 0: Vind fra mast mot spor - 1: Vind fra spor mot mast - 2: Vind parallelt spor Alternativer for ``type``: - 0: Bruddgrense - 1: Bruksgrense, forskyvning totalt - 2: Bruksgrense, forskyvning KL :param Mast mast: Aktuell mast :param Inndata i: Input fra bruker :param dict lastsituasjon: Aktuell lastsituasjon :param int vindretning: Aktuell vindretning :param int type: (Rad, etasje) for plassering i R- og D-matrise :param list F: Liste med :class:`Kraft`-objekter påført systemet :param numpy.array R: Reaksjonskraftmatrise :param numpy.array D: Forskyvningsmatrise :param float G: Lastfaktor egenvekt :param float L: Lastfaktor kabelstrekk :param float T: Lastfaktor temperatur :param float S: Lastfaktor snø/is :param float V: Lastfaktor vind :param iterasjon: Iterasjon for utregning av aktuell :class:`Tilstand` """ self.metode = "EC3" if i.ec3 else "NEK" self.lastsituasjon = lastsituasjon self.vindretning = vindretning self.type = type self.iterasjon = iterasjon if self.type == 0: # Bruddgrensetilstand self.F = copy.copy(F) self.R = R self.K = numpy.sum(numpy.sum(R, axis=0), axis=0) self.G = G self.L = L self.T = T self.S = S self.V = V self.faktorer = {"G": G, "L": L, "T": T, "S": S, "V": V} self.N_kap = abs(self.K[4] * mast.materialkoeff / (mast.fy * mast.A)) self.My_kap = abs(1000 * self.K[0] * mast.materialkoeff / (mast.fy * mast.Wy_el)) self.Mz_kap = abs(1000 * self.K[2] * mast.materialkoeff / (mast.fy * mast.Wz_el)) self.utnyttelsesgrad = self._utnyttelsesgrad(i, mast, self.K) if "Ulykkeslast" in lastsituasjon: self.lastsituasjon = "Ulykkeslast" else: # Bruksgrensetilstand self.R = R self.D = D self.K = numpy.sum(numpy.sum(R, axis=0), axis=0) self.K_D = numpy.sum(numpy.sum(D, axis=0), axis=0)
def __repr__(self): K = self.K / 1000 # Konverterer M til [kNm] og F til [kN] if self.type == 0: rep = "" # for j in self.F: # rep += j.rep() rep += "Beregningsmetode: {}\n".format(self.metode) rep += "My = {:.3g} kNm Vy = {:.3g} kN Mz = {:.3g} kNm " \ "Vz = {:.3g} kN N = {:.3g} kN T = {:.3g} kNm\n". \ format(K[0], K[1], K[2], K[3], K[4], K[5]) rep += "Lastsituasjon: {}\n".format(self.lastsituasjon) rep += "Iterasjon = {}\n".format(self.iterasjon) if self.lastsituasjon is not "Ulykkeslast": for key in self.faktorer: rep += "{} = {} ".format(key, self.faktorer[key]) rep += "\n" rep += "Vindretning = {}\n".format(self.vindretning) rep += "My_kap: {:.3g}% Mz_kap: {:.3g}% " \ "N_kap: {:.3g}%\n".format(self.My_kap * 100, self.Mz_kap * 100, self.N_kap * 100) rep += "Sum kapasiteter: {}%\n".format(self.My_kap * 100 + self.Mz_kap * 100 + self.N_kap * 100) rep += "Utnyttelsesgrad: {}%\n".format(self.utnyttelsesgrad * 100) else: rep = "" rep += "Dy = {:.3f} mm Dz = {:.3f} mm phi = {:.3f}\n". \ format(self.K_D[0], self.K_D[1], self.K_D[2]) rep += "My = {:.3g} kNm Vy = {:.3g} kN Mz = {:.3g} kNm " \ "Vz = {:.3g} kN N = {:.3g} kN T = {:.3g} kNm\n". \ format(K[0], K[1], K[2], K[3], K[4], K[5]) rep += "Lastsituasjon: {}\n".format(self.lastsituasjon) rep += "Iterasjon = {}\n".format(self.iterasjon) rep += "Vindretning = {}\n".format(self.vindretning) return rep
[dokumentasjon] def _beregn_momentfordeling(self): """Beregner mastens momentfordeling. Beregner ekvivalent mastelengde L_e, samt andeler til kritisk moment. A gir vindlastens, mens B angir punktlastenes andel av bidrag til kritisk moment. :return: Ekvivalent mastelengde ``L_e`` :math:`[mm]`, momentandeler ``A`` og ``B`` :rtype: :class:`float`, :class:`float`, :class:`float` """ M_punkt, M_fordelt, M_fordelt_0, M_sum = 0, 0, 0, 0 # (0) Vind fra mast mot spor eller (1) fra spor mot mast if self.vindretning == 0 or 1: for j in self.F: f = j.f if not numpy.count_nonzero(j.q) == 0: if self.vindretning == 0: f = numpy.array([0, 0, j.q[2] * j.b]) elif self.vindretning == 1: f = numpy.array([0, 0, j.q[2] * j.b]) M_fordelt_0 += abs(f[2] * j.e[0]) M_fordelt += abs(f[2] *j.e[0] ** 2) else: M_punkt += abs(f[2] * j.e[0] ** 2) M_sum += abs(f[2] * j.e[0]) # (2) Vind parallelt spor elif self.vindretning == 2: # Beregner ekvivalent mastelengde for j in self.F: f = j.f if not numpy.count_nonzero(j.q) == 0: f = numpy.array([0, j.q[1] * j.b, 0]) M_fordelt_0 += abs(f[2] * j.e[0]) M_fordelt += abs(f[1] * j.e[0] ** 2) else: M_punkt += abs(f[1] * j.e[0] ** 2) M_sum += abs(f[1] * j.e[0]) L_e = 1000 * (M_punkt + M_fordelt) / M_sum # [mm] A = abs(M_fordelt_0 / M_sum) B = 1 - A return L_e, A, B
[dokumentasjon] def _reduksjonsfaktor_knekking(self, mast, L_cr, akse): """Beregner faktorer for aksialkraftkapasitet etter EC3, 6.3.1.2. ``akse`` styrer beregning om hhv. sterk og svak akse: - 0: Beregner knekkfaktorer om y-aksen - 1: Beregner knekkfaktorer om z-aksen :param Mast mast: Aktuell mast :param float L_cr: Effektiv mastelengde :math:`[mm]` :param int akse: Aktuell akse :return: Reduksjonsfaktor ``X`` for knekking, slankhet ``lam`` :rtype: :class:`float`, :class:`float` """ if akse == 0: N_cr = (math.pi ** 2 * mast.E * mast.Iy(mast.h)) / (L_cr ** 2) lam = math.sqrt((mast.A * mast.fy) / N_cr) alpha = 0.34 if not mast.type == "B" else 0.49 phi = 0.5 * (1 + alpha * (lam - 0.2) + lam ** 2) X = 1 / (phi + math.sqrt(phi ** 2 - lam ** 2)) else: N_cr = (math.pi ** 2 * mast.E * mast.Iz(mast.h)) / (L_cr ** 2) lam = math.sqrt((mast.A * mast.fy) / N_cr) alpha = 0.49 if not mast.type == "H" else 0.34 phi = 0.5 * (1 + alpha * (lam - 0.2) + lam ** 2) X = 1 / (phi + math.sqrt(phi ** 2 - lam ** 2)) X = X if X <= 1.0 else 1.0 return X, lam
[dokumentasjon] def _reduksjonsfaktor_vipping(self, mast, L_e, A, B, My_Ed): """Bestemmer reduksjonsfaktoren for vipping etter EC3, 6.3.2.2 og 6.3.2.3. :param Mast mast: Aktuell mast :param float L_e: Effektiv mastelengde :math:`[mm]` :param float A: Momentandel fra vindlast :param float B: Momentandel fra punktlaster :return: Reduksjonsfaktor for vipping :rtype: :class:`float` """ X_LT = 1.0 if not mast.type == "H": # H-masten har ingen parameter It. my_vind, my_punkt = 2.05, 1.28 gaffel_v = math.sqrt(1 + (mast.E * mast.Cw / (mast.G * mast.It)) * (math.pi / L_e) ** 2) # Antar at lasten angriper i skjærsenteret, z_a == 0. M_cr_vind = my_vind * (math.pi / L_e) * math.sqrt(mast.G * mast.It * mast.E * mast.Iz(mast.h)) * gaffel_v M_cr_punkt = my_punkt * (math.pi / L_e) * math.sqrt(mast.G * mast.It * mast.E * mast.Iz(mast.h)) * gaffel_v M_cr = A * M_cr_vind + B * M_cr_punkt lam_LT = math.sqrt(mast.My_Rk / M_cr) lam_0, beta = 0.4, 0.75 if lam_LT > lam_0 and (My_Ed / M_cr) > lam_0 ** 2: if mast.type == "B": alpha_LT = 0.76 phi_LT = 0.5 * (1 + alpha_LT * (lam_LT - 0.2) + lam_LT ** 2) X_LT = 1 / (phi_LT + math.sqrt(phi_LT**2 - lam_LT**2)) X_LT = X_LT if X_LT <= 1.0 else 1.0 elif mast.type == "bjelke": alpha_LT = 0.34 phi_LT = 0.5 * (1 + alpha_LT * (lam_LT - lam_0) + beta * lam_LT**2) X_LT = 1 / (phi_LT + math.sqrt(phi_LT**2 - beta * lam_LT**2)) if X_LT > min(1.0, (1 / lam_0 ** 2)): X_LT = min(1.0, (1 / lam_0 ** 2)) return X_LT
[dokumentasjon] def _interaksjonsfaktorer(self, mast, lam_y, N_Ed, X_y, X_z, lam_z): """Beregner interaksjonsfaktorer etter EC3, Tabell B.2. Det antas at alle master tilhører tverrsnittsklasse #1. :param Mast mast: Aktuell mast :param float lam_y: Relativ slankhet for knekking om y-aksen :param float N_Ed: Dimensjonerende aksialkraft :math:`[N]` :param float X_y: Reduksjonsfaktor for knekking om y-aksen :param float X_z: Reduksjonsfaktor for knekking om z-aksen :param float lam_z: Relativ slankhet for knekking om y-aksen :return: Interaksjonsfaktorer ``k_yy``, ``k_yz``, ``k_zy``, ``k_zz`` :rtype: :class:`float`, :class:`float`, :class:`float`, :class:`float` """ k_yy = 0.6 * (1 - (lam_y - 0.2) * (1.05 * N_Ed / (X_y * mast.A * mast.fy))) k_yy_max = 0.6 * (1 + 0.8 * (1.05 * N_Ed / (X_y * mast.A * mast.fy))) if k_yy > k_yy_max: k_yy = k_yy_max if lam_z < 0.4: k_zy = 0.6 + lam_z k_zy_max = 1 - (0.1 * lam_z / (0.6 - 0.25)) * (1.05 * N_Ed / (X_z * mast.A * mast.fy)) if k_zy > k_zy_max: k_zy = k_zy_max else: k_zy_1 = 1 - (0.1 * lam_z / (0.6 - 0.25)) * (1.05 * N_Ed / (X_z * mast.A * mast.fy)) k_zy_2 = 1 - (0.1 / (0.6 - 0.25)) * (1.05 * N_Ed / (X_z * mast.A * mast.fy)) k_zy = max(k_zy_1, k_zy_2) k_zz = 0.6 * (1 + (2 * lam_z - 0.6) * (1.05 * N_Ed / (X_z * mast.A * mast.fy))) k_zz_max = 0.6 * (1 + 1.4 * (1.05 * N_Ed / (X_z * mast.A * mast.fy))) if k_zz > k_zz_max: k_zz = k_zz_max k_yz = 0.6 * k_zz return k_yy, k_yz, k_zy, k_zz
[dokumentasjon] def _utnyttelsesgrad(self, i, mast, K): """Beregner utnyttelsesgrad. Funksjonen undersøker utnyttelsesgrad for alle relevante bruddsituasjoner, og returnerer den høyeste verdien. :param Inndata i: Input fra bruker :param Mast mast: Aktuell mast :param list K: Liste med dimensjonerende reaksjonskrefter :return: Mastens utnyttelsesgrad :rtype: :class:`float` """ u = self.N_kap + self.My_kap + self.Mz_kap L_e, A, B = self._beregn_momentfordeling() L_cr = 2 * L_e if i.avspenningsmast or i.fixavspenningsmast: L_cr = L_e # Konverterer [Nm] til [Nmm] My_Ed, Mz_Ed = 1000 * abs(K[0]), 1000 * abs(K[2]) Vy_Ed, Vz_Ed, N_Ed = abs(K[1]), abs(K[3]), abs(K[4]) X_y, lam_y = self._reduksjonsfaktor_knekking(mast, L_cr, 0) X_z, lam_z = self._reduksjonsfaktor_knekking(mast, L_cr, 1) X_LT = self._reduksjonsfaktor_vipping(mast, L_e, A, B, My_Ed) My_Rk, Mz_Rk, N_Rk = mast.My_Rk, mast.Mz_Rk, mast.A * mast.fy k_yy, k_yz, k_zy, k_zz = self._interaksjonsfaktorer(mast, lam_y, N_Ed, X_y, X_z, lam_z) # EC3, 6.3.3(4) ligning (6.61) UR_y = (1.05 * N_Ed / (X_y * mast.A * mast.fy)) + \ k_yy * (1.05 * My_Ed / (X_LT * My_Rk)) + \ k_yz * (1.05 * Mz_Ed / Mz_Rk) # EC3, 6.3.3(4) ligning (6.62) UR_z = (1.05 * N_Ed / (X_z * mast.A * mast.fy)) + \ k_zy * (1.05 * My_Ed / (X_LT * My_Rk)) + \ k_zz * (1.05 * Mz_Ed / Mz_Rk) UR_d, UR_g = 0, 0 if mast.type == "H": # Diagonalstav: N_Ed_d = max(math.sqrt(2)/2 * Vy_Ed, math.sqrt(2)/2 * Vz_Ed) L_d = mast.k_d * mast.d_L d_I = mast.d_I alpha_d = 0.49 N_cr_d = (math.pi**2 * mast.E * d_I) / (L_d**2) lam_d = math.sqrt(mast.d_A * mast.fy / N_cr_d) phi_d = 0.5 * (1 + alpha_d * (lam_d - 0.2) + lam_d ** 2) X_d = 1 / (phi_d + math.sqrt(phi_d**2 - lam_d**2)) UR_d = (1.05 * N_Ed_d / (X_d * mast.d_A * mast.fy)) # Gurt (vinkelprofil) N_Ed_g = 0.5*((My_Ed/mast.bredde(mast.h-1)) + (Mz_Ed/mast.bredde(mast.h-1)) + Vy_Ed + Vz_Ed) + N_Ed/4 L_g = mast.k_g * 1000 I_g = mast.Iy_profil alpha_g = 0.34 N_cr_g = (math.pi**2 * mast.E * I_g) / (L_g**2) lam_g = math.sqrt(mast.A_profil * mast.fy / N_cr_g) phi_g = 0.5 * (1 + alpha_g * (lam_g - 0.2) + lam_g ** 2) X_g = 1 / (phi_g + math.sqrt(phi_g**2 - lam_g**2)) UR_g = (1.05 * N_Ed_g / (X_g * mast.A_profil * mast.fy)) return max(u, UR_y, UR_z, UR_d, UR_g)