#!/usr/bin/env python # coding: utf-8 #

Simple beam modeling

#
# #
# In[ ]: try: import piplite await piplite.install(['ipywidgets==7.7.0', 'ipyflex', 'plotly', 'cosapp']) except: pass # In[1]: from cosapp.ports import Port from cosapp.systems import System import numpy as np class GeometryPort(Port): def setup(self): self.add_variable("visible", True, desc="Should this geometry be shown?") self.add_variable("shape", None, desc="Geometrical object") class BeamGeo(System): def setup(self): self.add_inward("file","path") self.add_inward("mesh_size",100) self.add_inward('width', 0.5, unit = 'm') self.add_inward('height',0.5, unit = 'm') self.add_inward('length', 5., unit = 'm') self.add_outward('I', desc='Second area moment') self.add_outward('grid', np.zeros(1)) self.add_outward("section", []) self.add_output(GeometryPort, 'geom') def compute(self): self.I = self.width*self.height**3/12. self.grid = np.array([i*self.length/self.mesh_size for i in range(0,int(self.mesh_size)+1)]) section = [[],[]] for i in range(0,100): section[0].append((- 0.5 + i/100.)*self.width) section[1].append(-0.5*self.height) for i in range(0,100): section[0].append(0.5*self.width) section[1].append((- 0.5 + i/100.)*self.height) for i in range(0,100): section[0].append((0.5 - i/100.)*self.width) section[1].append(0.5*self.height) for i in range(0,100): section[0].append( -0.5*self.width) section[1].append((0.5 - i/100.)*self.height) self.section = section # In[2]: class BeamMeca(System): def setup(self): self.add_inward('E', 270, desc = "Young modulus", valid_range = [100,150],limits = [50,200]) self.add_inward("grid", np.zeros(101), valid_range = [2,4],limits = [-np.inf,10] ) self.add_inward("I", 1., desc='Second area moment' ) self.add_inward("force", -1., desc='Force value', unit = 'N' ) self.add_inward("position", 0.5, desc="force relative position",limits= [0.2,0.3], valid_range = [0.1,0.8] ) self.add_outward("M", np.zeros(1), desc = "Bending moments" ) self.add_outward("Q", np.zeros(1), desc = "Shear forces" ) self.add_outward("W", np.zeros(1), desc = "Deflections" ) self.add_outward("maxW", 0, desc = "Max deflections" ) self.add_outward("f_position", 0.5, desc="force position") self.add_outward("maxW_loc", 0, desc = "Max deflections location" ) def compute(self): if self.position > 1.: position = 0.99 elif self.position < 0: position = 0. else: position = self.position mesh_size = len(self.grid) L = self.grid[-1] b = (1.- position)*L a = position*L M =[] Q = [] W = [] for i in range(0, int(mesh_size*position)): x = self.grid[i] M.append(self.force*b*x/L) Q.append(self.force*b/L) W.append(self.force*b*x*(L**2 - b**2 - x**2)/(6*L*self.E*self.I)) for j in range(int(mesh_size*position), mesh_size): x = self.grid[j] M.append(self.force*a*(L - x)/L) Q.append(self.force*(b/L-1)) W.append(self.force*b*x*(L**2 - b**2 - x**2)/(6*L*self.E*self.I)+ self.force*(x-a)**3/(6*self.E*self.I)) self.M = np.array(M) self.Q = np.array(Q) self.W = np.array(W) self.maxW_loc = int(np.argmax(np.absolute(self.W)))-1 self.maxW = self.W[self.maxW_loc] self.f_position = mesh_size*position # In[3]: class Main(System): def setup(self): self.add_inward("maintest",0) self.add_child(BeamGeo("geo")) self.add_child(BeamMeca("meca")) self.connect(self.geo.outwards, self.meca.inwards, ["I", "grid"]) # In[4]: main = Main("main") main.run_drivers() # In[5]: import ipywidgets import ipyflex import plotly.graph_objects as go # In[6]: widget_M = go.FigureWidget(go.Bar( y=main.meca.M, # marker_color='rgba(91, 91, 91, 0.73)', name='M', )) widget_Q = go.FigureWidget(go.Scatter( y=main.meca.Q , # marker_color='rgba(91, 91, 91, 0.73)', name='M', )) widget_W = go.FigureWidget(go.Bar( y=main.meca.W, # marker_color='rgba(91, 91, 91, 0.73)', name='M', ), layout_yaxis_range=[-10,0]) # In[6]: # In[7]: E_slider = ipywidgets.FloatSlider( value=150, min=50, max=250,description='Young modulus:', continuous_update=False,) def on_E_change(change): main.meca.E = change['new'] main.run_drivers() widget_M.data[0].y = main.meca.M widget_Q.data[0].y = main.meca.Q widget_W.data[0].y = main.meca.W E_slider.observe(on_E_change, names='value') position_slider = ipywidgets.FloatSlider( value=0.5, min=0.1, max=0.8, continuous_update=False, description='Force position',) def on_position_change(change): main.meca.position = change['new'] main.run_drivers() widget_M.data[0].y = main.meca.M widget_Q.data[0].y = main.meca.Q widget_W.data[0].y = main.meca.W position_slider.observe(on_position_change, names='value') control = ipywidgets.VBox([E_slider, position_slider]) # In[8]: widget_dict = {'Moment': widget_M, 'Deflection': widget_W, 'Shear forces':widget_Q, 'Control': control} w = ipyflex.FlexLayout(widget_dict, template='beam.json', editable=False, header={'title':'Simply supported beam', 'buttons':[]}, ) # In[9]: w # In[9]: # In[9]: