paint-brush
Python ve Viktor'u Kullanarak Çelik Taban Plaka Tasarımı Web Uygulaması Nasıl Oluşturulurile@kamalsamaila
377 okumalar
377 okumalar

Python ve Viktor'u Kullanarak Çelik Taban Plaka Tasarımı Web Uygulaması Nasıl Oluşturulur

ile Kamal samaila18m2024/05/06
Read on Terminal Reader

Çok uzun; Okumak

Bu makale, kolon yüklerini temellere güvenli bir şekilde aktarmak için gerekli olan çelik taban plakalarını tasarlamak için Python tabanlı bir uygulama oluşturma konusunda size rehberlik eder. T-saplama yöntemini kullanarak taban plakası alanının, kalınlığının, beton taşıma mukavemetinin ve ilave genişliğin hesaplanmasını kapsar. Python kodu daha sonra Viktor SDK kullanılarak bir web uygulamasına dönüştürülerek mühendislerin parametreleri girmesine ve yapının 3 boyutlu modellerini görselleştirmesine olanak tanınıyor. Bu etkili araç, taban plakası tasarımlarının doğruluğunu artırır ve mobil cihazlar aracılığıyla saha kontrollerini kolaylaştırarak inşaat iş akışını kolaylaştırır.
featured image - Python ve Viktor'u Kullanarak Çelik Taban Plaka Tasarımı Web Uygulaması Nasıl Oluşturulur
Kamal samaila HackerNoon profile picture

giriiş

Tasarım kuvvetlerini güvenli bir şekilde temellere aktarmak için çelik taban plakaları çelik kolonların altına yerleştirilir.


Çelik kolonlar küçük kesitli ağır yükler taşıdığında, yüklerin doğrudan temele uygulanması zımbalama arızalarına neden olabilir. Bu nedenle yükü daha geniş bir alana dağıtmak için kolonun altında bir taban plakası kullanılması çok önemlidir.


Bu makale, CSV formatında depolanan çelik geometrik özelliklerinden yararlanarak Python kullanarak bir taban plakası tasarım uygulaması oluşturmaya yönelik bir kılavuz sağlar.


Uygulama, mühendislere gerekli taban plakası alanını, kalınlığını, beton taşıma mukavemetini ve ek genişliği kolayca belirlemede yardımcı olacaktır.


Ayrıca Viktor SDK'yı kullanarak Python uygulamamızı sorunsuz bir şekilde bir web uygulamasına dönüştürebiliriz.


Bu SDK, yapımızı 3 boyutlu görünümde görselleştirme yeteneği sunar. Hemen dalalım ve harekete geçelim!

Taban Plakasının Tasarımının Temel Prensibi

Taban plakası tasarımı, eksenel kuvvetler için eşdeğer T saplama yöntemini kullanır; burada basınç altındaki T saplamalar için 'Etkili alan' hesaplanır ve gerilim altındaki T saplamalar için taban plakası bükülmesi değerlendirilir. Yatay büyük ve/veya küçük kesmeye izin verilir, ancak momentlere (örneğin sabitlenmiş taban tasarımı) izin verilmez.

Hesapladığımız ilk şey, destek betonunun taşıma gücü fjd'dir.

Taban plakasının alt tarafı ile enjeksiyon alanındaki yatak malzemesi arasındaki tasarım taşıma mukavemeti fjd şu şekilde verilir:


fjd = βj * α * fcd

Neresi


βj = Temel birleşim malzemesi katsayısı = (2/3)


α = yoğunlaşmış kuvvetin temel içerisinde yayılmasını açıklayan bir katsayı


fcd = tasarım değeri beton basınç dayanımı = αcc * fck / ɣc


αcc = uzun vadeli etkiler için katsayı


fck = beton karakteristik silindir dayanımı


ɣc = beton için kısmi güvenlik faktörü

İkinci adım, aşağıdaki formülle verilen gerekli taban plakası alanını hesaplamaktır:

Areq = Ned / fjd

Ned'in çelik kolondan gelen nihai yük olduğu yer.

Üçüncü adım, etkin alanın konsol çıkıntısı olan c'yi hesaplamaktır:

C aşağıdaki formül kullanılarak hesaplanır:

Aeff = 4 *( c**2) + PCol * c + Akol


Dolayısıyla c'yi çözersiniz.


Son olarak taban plakasının kalınlığını (tp) hesaplıyoruz:

tp = c * (3 * fjd* Ym0 / _page_fy)**0,50

Taban Plakası Tasarımı İş Akışının Python Uygulaması

 # Partial factor of resistance of cross-sections whatever the class is as per EN 1993-1-1. Ym0 = 1.0 # Compute foundation bearing strength which is typically concrete #βj is the foundation joint material coefficient, typically taken as 0.67 as per clause 6.2.5(7) in EN 1993-1-8. beta_j=0.67 #α is a coefficient of diffusion of the vertical load being applied to the foundation. Conservatively this can be taken as 1.5 alpha= 1.5 # αcc is the coefficient that allows for long-term effects on the compressive strength of concrete vs applied actions. Taken as 0.85 in the UK National Annex -> on page # Define alpha_cc # Define gamma_c # define fck # γc is the partial factor of safety of concrete. Taken as 1.5 in the UK National Annex -> on page fjd = beta_j*alpha* (alpha_cc*fck )/gamma_c # Compute the area of the baseplate required Areq = (Ned *1000)/ fjd #Ned is the Ultimate load def calculate_c(Pcol, Acol, Areq): # """ # This function calculates the value of c for the given equation: # Areq = 4 * c^2 + P_col * c + A_col # Args: # Perimeter_of_section: Perimeter of the column section (mm) # Area_of_section: Area of the column section (mm²) # Areq: Required area of the baseplate (mm²) # Returns: # The value of c (mm) # """ a = 4 b = Pcol c = Acol-Areq # Assuming Areq is already calculated discriminant = b**2 - 4 * a * c c1 = (-b + (discriminant)**0.5) / (2 * a) c2 = (-b - (discriminant)**0.5) / (2 * a) return max(c1, c2) c = calculate_c(Pcol,Acol,Areq) # Compute the thickness of the baseplate (tp) tp = c * (3 * fjd* Ym0 / _page_fy)**0.50

Son olarak Python Kodunu Taban Plakası Tasarımı için Web Uygulamasına Dönüştürmek

Giriş

Son uygulamam, kullanıcının aşağıdaki parametreleri belirleyebileceği giriş özelliklerine ihtiyaç duyacaktır:

Bu, Viktor SDK'daki parametrelendirme sınıfı kullanılarak elde edilir.

 class Parametrization(ViktorParametrization): input = Tab("Input") input.profile_type = OptionField( "Profile type", options=["IPE", "HEA", "HEB"], default="IPE", variant="radio-inline", flex=80, ) input.nl1 = LineBreak() input.profile = AutocompleteField( "Profile", options=get_profile_types, default="IPE240", description="The source of profile properties can be found [here](https://eurocodeapplied.com/design/en1993/ipe-hea-heb-hem-design-properties)", ) # input.steel_class = OptionField( # "Steel class", options=["S235", "S275", "S355"], default="S235" # ) input.fck = NumberField('Fck', default=25, suffix="MPa") input.Design_load = NumberField('Design_load', default=1000, suffix="KN") input.acc = NumberField('Concrete coeff(acc)', default=0.85) input.yc = NumberField('Partial factor of safety for concrete', default=1.5) input.steel_class = NumberField('steel_class', default=255, suffix="MPa")


Çıktı

Hesaplamanın ardından, hesaplamanın sonucunu kullanıcıya görüntülemek için Viktor SDK'daki veri görüntüleme yöntemi kullanıldı.

 @DataView("Output", duration_guess=1) def Compute_output(self, params: Munch, **kwargs): Ym0, beta_j, alpha, fjd, Areq, c, tp = self.calculate_plate_geom(params) data = DataGroup( DataItem("ultimate load ", params.input.Design_load, suffix="KN"), DataItem("beta_j", 0.67), DataItem("alpha", 1.5), DataItem("Bearing capacity of concrete support(fjd) ", round(fjd), suffix="MPa"), DataItem("Areq ", round(Areq), suffix="mm2"), DataItem(" c", round(c), suffix="mm"), DataItem("Thickness of plate", round(tp), suffix="mm"), ) return DataResult(data)

Neresi:

Betonun taşıma kapasitesi(Fjd)

Gerekli çelik alanı (Areq)

Taban plakasının ek çıkıntısı(c)

Taban plakasının kalınlığı

Son olarak çelik kolonun, taban plakasının ve destekleyici beton temelin 3 boyutlu modeli oluşturulur.

@GeometryView ile süslenmiş denetleyici sınıfının içinde bir get_3dview yöntemi tanımlandı.


Get_3dview yöntemi, 3B modeli oluşturma mantığını tanımlayan yöntemdir ve son olarak oluşturulan çelik kolonu, taban plakasını ve beton desteği içeren GeometryResult nesnesini döndürür.


Mantık aşağıdaki kodda yer almaktadır:

 @GeometryView("3D baseplate View", duration_guess=1) def get_3dView(self, params: Munch, **kwargs): """Create geometry for column, base-plate and add a concrete slab underneath""" Ym0, beta_j, alpha, fjd, Areq, c, tp = self.calculate_plate_geom(params) concrete_thickness = 15 * tp steel = Material(color=Color(95, 158, 240), metalness=1) concrete = Material(metalness=0, roughness=1, opacity=0.6) h = self.get_profile_property(params.input.profile_type, params.input.profile, "Depth") b = self.get_profile_property(params.input.profile_type, params.input.profile, "Width") tw = self.get_profile_property(params.input.profile_type, params.input.profile, "Web thickness") tf = self.get_profile_property(params.input.profile_type, params.input.profile, "Flange thickness") r = self.get_profile_property(params.input.profile_type, params.input.profile, "Root radius") beam_profile = self.get_beam_profile(h, b, tw, tf, r) beam = Extrusion(beam_profile, Line(Point(0, 0, tp), Point(0, 0, 3 * h)), material=steel) base_plate = SquareBeam(sqrt(Areq), sqrt(Areq), tp, material=steel) # TODO: This area doesn't seem sufficient for large column sizes base_plate.translate((0, 0, tp / 2)) concrete_plate = SquareBeam(6 * h, 6 * h, concrete_thickness, material=concrete) concrete_plate.translate((0, 0, -concrete_thickness / 2)) return GeometryResult([beam, base_plate, concrete_plate]) 


Kodun tamamını aşağıda bulabilirsiniz:

 from math import sqrt # import plotly.express as px from pathlib import Path from typing import List import numpy as np import pandas as pd from munch import Munch from viktor import ViktorController, Color from viktor.geometry import Point, Extrusion, Line, Material, SquareBeam from viktor.parametrization import ( ViktorParametrization, OptionField, Text, Tab, AutocompleteField, LineBreak, NumberField ) # from viktor.external.spreadsheet import SpreadsheetCalculation, SpreadsheetCalculationInput from viktor.views import DataGroup, DataItem, DataResult, DataView, GeometryView, GeometryResult def get_profile_types(params: Munch, **kwargs): try: file_path = ( Path(__file__).parent / "profiles" / f"steel-profiles-{params.input.profile_type}.csv" ) df = pd.read_csv(file_path, header=[2], skiprows=[3, 4, 5]) return df["Profile"].values.tolist() except FileNotFoundError: return ["IPE80", "IPE100", "HEA100", "HEA120", "HEB100", "HEB120"] def calculate_c(Pcol, Acol, Areq): # """ # This function calculates the value of c for the given equation: # Areq = 4 * c^2 + P_col * c + A_col # Args: # Perimeter_of_section: Perimeter of the column section (mm) # Area_of_section: Area of the column section (mm²) # Areq: Required area of the baseplate (mm²) # Returns: # The value of c (mm) # """ a = 4 b = Pcol c = Acol - Areq # Assuming Areq is already calculated discriminant = b ** 2 - 4 * a * c c1 = (-b + (discriminant) ** 0.5) / (2 * a) c2 = (-b - (discriminant) ** 0.5) / (2 * a) return max(c1, c2) class Parametrization(ViktorParametrization): info = Tab("Info") info.text_01 = Text( """## Welcome to baseplate design app! """ ) input = Tab("Input") input.profile_type = OptionField( "Profile type", options=["IPE", "HEA", "HEB"], default="IPE", variant="radio-inline", flex=80, ) input.nl1 = LineBreak() input.profile = AutocompleteField( "Profile", options=get_profile_types, default="IPE240", description="The source of profile properties can be found [here](https://eurocodeapplied.com/design/en1993/ipe-hea-heb-hem-design-properties)", ) # input.steel_class = OptionField( # "Steel class", options=["S235", "S275", "S355"], default="S235" # ) input.fck = NumberField('Fck', default=25, suffix="MPa") input.Design_load = NumberField('Design_load', default=1000, suffix="KN") input.acc = NumberField('Concrete coeff(acc)', default=0.85) input.yc = NumberField('Partial factor of safety for concrete', default=1.5) input.steel_class = NumberField('steel_class', default=255, suffix="MPa") class Controller(ViktorController): label = 'My Entity Type' parametrization = Parametrization @DataView("profile geometrical Properties", duration_guess=1) def display_geometrical_properties(self, params: Munch, **kwargs): """Initiates the process of rendering an image of the bending moments of the structure, as well as a view of a few key values related to the bending moments.""" # results = self.calculate_allowable_bending_moment( # params.input.profile_type, params.input.profile # ) results = self.get_geometrical_properties( params.input.profile_type, params.input.profile ) data = DataGroup( DataItem("Depth", results["Depth"], suffix="mm"), DataItem("Width", results["Width"], suffix="mm"), DataItem("Thickness_of_web", results["Thickeness_of_web"], suffix="mm"), DataItem("Thickness_of_flange", results["Thickeness_of_flange"], suffix="mm"), DataItem("Area_col", results["Area_col"], suffix="mm2"), DataItem("Perimeter_col", results["Perimeter_col"], suffix="mm"), ) return DataResult(data) def calculate_plate_geom(self, params, **kwargs): results = self.get_geometrical_properties( params.input.profile_type, params.input.profile ) # Partial factor of resistance of cross-sections whatever the class is as per EN 1993-1-1. Ym0 = 1.0 # Compute ultimate load (Ned) -> on page # Compute foundation bearing strength which is typically concrete # βj is the foundation joint material coefficient, typically taken as 0.67 as per clause 6.2.5(7) in EN 1993-1-8. beta_j = 0.67 # α is a coefficient of diffusion of the vertical load being applied to the foundation. Conservatively this can be taken as 1.5 alpha = 1.5 # αcc is the coefficient that allows for long term effects on the compressive strength of concrete vs applied actions. Taken as 0.85 in the UK National Annex -> on page # γc is the partial factor of safety of concrete. Taken as 1.5 in the UK National Annex -> on page fjd = beta_j * alpha * (params.input.acc * params.input.fck) / params.input.yc # Compute area of baseplate required Areq = (params.input.Design_load * 1000) / fjd c = calculate_c(results["Perimeter_col"], results["Area_col"], Areq) # Compute the thickness of baseplate (tp) tp = c * (3 * fjd * Ym0 / params.input.steel_class) ** 0.50 return Ym0, beta_j, alpha, fjd, Areq, c, tp @DataView("Output", duration_guess=1) def Compute_output(self, params: Munch, **kwargs): Ym0, beta_j, alpha, fjd, Areq, c, tp = self.calculate_plate_geom(params) data = DataGroup( DataItem("ultimate load ", params.input.Design_load, suffix="KN"), DataItem("beta_j", 0.67), DataItem("alpha", 1.5), DataItem("Bearing capacity of concrete support(fjd) ", round(fjd), suffix="MPa"), DataItem("Areq ", round(Areq), suffix="mm2"), DataItem(" c", round(c), suffix="mm"), DataItem("Thickness of plate", round(tp), suffix="mm"), ) return DataResult(data) @staticmethod def get_beam_profile(h, b, tw, tf, r) -> List[Point]: """Generates the points which make up the chosen profile for the column cross-section""" # Get points for top flange points = [ Point(-b / 2, (h / 2) - tf), Point(-b / 2, h / 2), Point(b / 2, h / 2), Point(b / 2, (h / 2) - tf), ] # Get curve for top right angles = np.linspace(np.pi / 2, np.pi, 10) x = r * np.cos(angles) + tw / 2 + r y = r * np.sin(angles) + h / 2 - tf - r for _x, _y in zip(x, y): points.append(Point(_x, _y)) # Get curve for bottom right angles = np.linspace(-np.pi, -np.pi / 2, 10) x = r * np.cos(angles) + tw / 2 + r y = r * np.sin(angles) - h / 2 + tf + r for _x, _y in zip(x, y): points.append(Point(_x, _y)) # Get points for bottom flange points.extend([ Point(b / 2, - (h / 2) + tf), Point(b / 2, -h / 2), Point(-b / 2, -h / 2), Point(-b / 2, -(h / 2) + tf), ]) # Get curve for bottom left angles = np.linspace(1.5 * np.pi, 2 * np.pi, 10) x = r * np.cos(angles) - tw / 2 - r y = r * np.sin(angles) - h / 2 + tf + r for _x, _y in zip(x, y): points.append(Point(_x, _y)) # Get curve for top left angles = np.linspace(0, np.pi/2, 10) x = r * np.cos(angles) - tw / 2 - r y = r * np.sin(angles) + h / 2 - tf - r for _x, _y in zip(x, y): points.append(Point(_x, _y)) # Repeat the first point to close the profile points.append(Point(-b / 2, (h / 2) - tf)) return points @GeometryView("3D baseplate View", duration_guess=1) def get_3dView(self, params: Munch, **kwargs): """Create geometry for column, base-plate and add a concrete slab underneath""" Ym0, beta_j, alpha, fjd, Areq, c, tp = self.calculate_plate_geom(params) concrete_thickness = 15 * tp steel = Material(color=Color(95, 158, 240), metalness=1) concrete = Material(metalness=0, roughness=1, opacity=0.6) h = self.get_profile_property(params.input.profile_type, params.input.profile, "Depth") b = self.get_profile_property(params.input.profile_type, params.input.profile, "Width") tw = self.get_profile_property(params.input.profile_type, params.input.profile, "Web thickness") tf = self.get_profile_property(params.input.profile_type, params.input.profile, "Flange thickness") r = self.get_profile_property(params.input.profile_type, params.input.profile, "Root radius") beam_profile = self.get_beam_profile(h, b, tw, tf, r) beam = Extrusion(beam_profile, Line(Point(0, 0, tp), Point(0, 0, 3 * h)), material=steel) base_plate = SquareBeam(sqrt(Areq), sqrt(Areq), tp, material=steel) # TODO: This area doesn't seem sufficient for large column sizes base_plate.translate((0, 0, tp / 2)) concrete_plate = SquareBeam(6 * h, 6 * h, concrete_thickness, material=concrete) concrete_plate.translate((0, 0, -concrete_thickness / 2)) return GeometryResult([beam, base_plate, concrete_plate]) @staticmethod def get_profile_property( profile_type: str, profile: str, property_name: str ) -> float: """Retrieve the profile properties based on the profile type, profile and property :param profile_type: One of the following profile types: HEA, HEB or IPE. :param profile: Profile name, eg IPE80 (IPE was given as profile_type) :param property_name: The name of the property, eg Weight """ file_path = ( Path(__file__).parent / "profiles" / f"steel-profiles-{profile_type}.csv" ) df = pd.read_csv(file_path, header=[2], skiprows=[3, 4, 5]) return df.loc[df["Profile"] == profile, property_name].item() @staticmethod def get_geometrical_properties( profile_type: str, profile: str ): """Calculates the allowable bending moment based on the given parameters. :param profile_type: One of the following profile types: HEA, HEB or IPE. :param profile: Profile name, eg IPE80 (IPE was given as profile_type) :param steel_class: The steel class, eg S235 :return: A dict with the moment of inertia, profile height, yield strength and allowable bending moment. """ file_path = ( Path(__file__).parent / "profiles" / f"steel-profiles-{profile_type}.csv" ) df = pd.read_csv(file_path, header=[2], skiprows=[3, 4, 5]) Depth = df.loc[df["Profile"] == profile, "Depth"].item() Width = df.loc[df["Profile"] == profile, "Width"].item() Thickeness_of_web = df.loc[df["Profile"] == profile, "Web thickness"].item() Thickeness_of_flange = df.loc[df["Profile"] == profile, "Flange thickness"].item() Area_col = df.loc[df["Profile"] == profile, "Area"].item() Perimeter_col = df.loc[df["Profile"] == profile, "Perimeter"].item() Perimeter_col = Perimeter_col * 1000 return { "Depth": Depth, "Width": Width, "Thickeness_of_web": Thickeness_of_web, "Thickeness_of_flange": Thickeness_of_flange, "Area_col": Area_col, "Perimeter_col": Perimeter_col }


Çözüm

Kolon yüklerinin temele etkili bir şekilde iletilebilmesi için taban plakası kalınlığının ve sağlanması gereken etkin alanın kontrol edilmesi sorunuyla her zaman karşılaşıyorum.


Bu tür kontrollerde bana yardımcı olabilecek bir Python betiği kullanmak ve betiği Viktor SDK kullanarak paylaşılabilir ve erişimi kolay bir web uygulamasına dönüştürmek kolaydı ve taban plakası tasarımının iş akışına daha fazla verimlilik kazandırdı.


Bu tür bir mühendislik uygulaması oluşturmak, inşaat şantiyenizde yalnızca cep telefonunuzla kendinize güvenmenizi sağlayabilir ve taban plakaları gibi yapısal elemanların tasarım doğruluğunu, üretilmeden ve yerleştirilmeden önce kontrol edebilmenizi sağlayabilir.