diff --git a/README.md b/README.md index 76f2317..6f6eed3 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,40 @@ -# Project title +# DRIL Project - CIVIL-238 -Start the README file by stating the name of your project or the name of your repository. +This prject is part of the [DRIL fund](https://www.epfl.ch/education/educational-initiatives/cede/digitaltools/dril/) and it is focused in the Structural Mechanics course for Civil Engineer (CIVIL-238) at [EPFL](https://www.epfl.ch/en/). +It presents a number of visual tools (DEMOs) that are meant to support: +- the teaching with their self-explanatory, simple and complete aspects +- the learning thanks to their interactive, interesting and intuitive sides ## Project description -We recommend that you provide a short description of your project, making sure to include relevant keywords for indexing. -The goal of this repository is to provide you with _template files_ that help you initialize your repository and that you can modify to fit your own needs and your own project. +The goal is to provide the student with interactive visual tools for understanding, playing and enjoying the complex aspects of the Structural Mechanics and to help the teacher by showing practical end exhaustive cases. -Then it is important to state the names of the authors and contributors of the project. -The contributors of this repository and the included template files are Cécile Hardebolle, Pierre-Olivier Vallès and Patrick Jermann, from the Center for Digital Education at EPFL. +The DEMOs are Jupyter Notebooks developed in Python (for the structure and initialisation) and Javascript (for the dynamic visual and plots). The main contents of these visual tools are: -It is good practice to include the public URL of your repository. -This repository is available at: https://c4science.ch/source/noto-poc-notebooks/ +- Simply supported beam as the statis system +- Two cross section: filled and hollow rectangular section +- Free-body diagram (FBD) +- NVM diagrams +- Deflection (only due to bending) +- Elastic and plastic analysis +- Stress and strain analysis +- Stress state element and stresses +- Torsion (uniform) +- Mohr Circle +- Buckling + +The contributors of this projects are + +- Carmine Schipani ([author](https://github.com/DonCammne)) +- Prof. D. Lignos (supervisor of the project and director of the [RESSLab](https://github.com/AlbanoCastroSousa/RESSPyLab)) +- Cécile Hardebolle and Pierre-Olivier Vallès from the [Center for Digital Education at EPFL](https://www.epfl.ch/education/educational-initiatives/cede/) (project directors). + +This repository is available at [this link](https://c4science.ch/diffusion/12408/). -And finally, contact information can also be helpful. For any enquiries relating to this template or this repository, please contact: [noto-support@groupes.epfl.ch](mailto:noto-support@groupes.epfl.ch) ## Copyright and license -Providing licensing information is very important. A brief summary should be included into your README and then you should also provide a more detailed LICENSE file. - All content in this repository is distributed publicly and openly under a Creative Commons Attribution license, [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/), and all code is under [BSD-3-Clause](LICENSE.md). -## Table of contents -This repository contains: -* a template `.gitignore` file -* a template `README.md` file -* a templace `LICENSE.md` file -* an example notebook diff --git a/Simple Beam DEMOs/sb_actions.ipynb b/Simple Beam DEMOs/sb_actions.ipynb new file mode 100644 index 0000000..69a57ed --- /dev/null +++ b/Simple Beam DEMOs/sb_actions.ipynb @@ -0,0 +1,718 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Actions\n", + "In this second notebook, different actions are applied on the simple supported beam. The internal forces and moments can be visuallized and the N V M graphs are presented. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import numpy as np\n", + "import math\n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer, Text\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "q = 4; # [kN/m]\n", + "P = 10; # [kN]\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_Q = q/4*5\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " q=[q],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 1 - Geo):" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
GlyphRenderer(
id = '2471', …)
coordinates = None,
data_source = ColumnDataSource(id='2467', ...),
glyph = Text(id='2468', ...),
group = None,
hover_glyph = None,
js_event_callbacks = {},
js_property_callbacks = {},
level = 'glyph',
muted = False,
muted_glyph = Text(id='2470', ...),
name = None,
nonselection_glyph = Text(id='2469', ...),
selection_glyph = 'auto',
subscribed_events = [],
syncable = True,
tags = [],
view = CDSView(id='2472', ...),
visible = True,
x_range_name = 'default',
y_range_name = 'default')
\n", + "\n" + ], + "text/plain": [ + "GlyphRenderer(id='2471', ...)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# Helmet for scale (if not visualized, remove this part because the browser don't support it correctly)\n", + "h_img = 180 # mm\n", + "fig_section.image_url(url=['https://www.jing.fm/clipimg/full/191-1917043_engineer-helmet-png-free-download-civil-engineer-cap.png'], x=-h_img/2, y=-MAX_H/2*1.05, h=h_img, w=h_img*701/535)\n", + "fig_section.text(x=[0], y=[-MAX_H/2-h_img*1.15], text_align=\"center\", text=[f\"Civil Engineer's helmet for scale (h={h_img} mm)\"], text_font_size=\"10px\")\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# uniform load (beam)\n", + "u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE], width=L, height=q/SCALE,\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + "label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "beam_position = fig_beam.circle('x', 'y', **pos_opt)\n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head)\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update data\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{models.implement_check_stateJS()}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b_h = dict(source=source,\n", + " s_b=source_beam,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b_h, code=code_change_b)\n", + "\n", + "\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = db['b'][0]\n", + "const h = cb_obj.value // value of the slider\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_b_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head)\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "\n", + "// apply the changes\n", + "db['P'][0] = {P}*(1-f)\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head)\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['q'][0] = q\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_beam,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout),\n", + " slider_b,\n", + " slider_h,\n", + " div_geo,\n", + " Spacer(height=padding_layout),\n", + " slider_position,\n", + " slider_q,\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P))),\n", + " column(fig_scheme,\n", + " Spacer(height=padding_layout),\n", + " div_forces))\n", + " )],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_buckling.ipynb b/Simple Beam DEMOs/sb_buckling.ipynb new file mode 100644 index 0000000..34341ed --- /dev/null +++ b/Simple Beam DEMOs/sb_buckling.ipynb @@ -0,0 +1,644 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Buckling\n", + "In this second notebook, the instability of a simple beam under constant axial load is studied. " + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import numpy as np\n", + "import math\n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer\n", + "from bokeh.models.widgets import RadioButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "from cienpy import buckling\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 100 # [mm]\n", + "b = 50 # [mm]\n", + "P = 10; # [kN]\n", + "\n", + "# Material parameter\n", + "E = 200e3 # MPa\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N = sb.compute_N(L, P)\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "\n", + "# compute buckling resistance\n", + "n_bracey = 0\n", + "n_bracez = 0\n", + "Ncrity = buckling.compute_N_buckling_y(E, Iy, L, n_bracey)\n", + "Ncritz = buckling.compute_N_buckling_z(E, Iz, L, n_bracez)\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_P = 100*P\n", + "MAX_L = 10\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " E=[E],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " Rx=[Rx],\n", + " N=[N],\n", + " Ncrity=[Ncrity],\n", + " Ncritz=[Ncritz],\n", + " n_bracey=[n_bracey],\n", + " n_bracez=[n_bracez],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 2 - Actions):" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "DIV_B_GEO = 170\n", + "DIV_B_FORCES = 170\n", + "\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "MAX_Q = 5\n", + "OFFSET_Q = 4\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(width= DIV_B_GEO,\n", + " text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# change title in beam (y direction)\n", + "fig_beam.title.text = \"Simple supported beam: x-y plane\"\n", + "\n", + "\n", + "# beam in z direction\n", + "fig_beam_z = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "fig_beam_z.title.text = \"Simple supported beam: x-z plane\"\n", + "(beam_z, support_l_z, support_r_z) = sb.draw_beam(fig_beam_z, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "fig_beam_z.x_range = fig_beam.x_range\n", + "\n", + "\n", + "# axial force (beam z direction)\n", + "axial_force_z = models.force_vector(fig_beam_z, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force_z = fig_beam_z.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# reference system (x-y plane)\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_beam, axis_arrow_length, -axis_arrow_length-0.1, -0.1, 0, 0, 'gray')\n", + "fig_beam.text(x=[-axis_arrow_length], y=[0.1], text=[\"x axis\"], text_color='gray', text_baseline='bottom')\n", + "models.force_vector(fig_beam, axis_arrow_length, 0, 0, 0, axis_arrow_length, 'gray')\n", + "fig_beam.text(x=[0.1], y=[0.2], text=[\"y axis\"], text_color='gray', text_baseline='bottom')\n", + "\n", + "\n", + "# reference system (x-z plane)\n", + "models.force_vector(fig_beam_z, axis_arrow_length, -axis_arrow_length-0.1, -0.1, 0, 0, 'gray')\n", + "fig_beam_z.text(x=[-axis_arrow_length], y=[0.1], text=[\"x axis\"], text_color='gray', text_baseline='bottom')\n", + "models.force_vector(fig_beam_z, axis_arrow_length, 0, 0, 0, axis_arrow_length, 'gray')\n", + "fig_beam_z.text(x=[0.1], y=[0.2], text=[\"z axis\"], text_color='gray', text_baseline='bottom')\n", + "\n", + "\n", + "# slider P\n", + "slider_P = Slider(\n", + " title=\"Change the axial force P [kN]\",\n", + " start=1,\n", + " end=MAX_P,\n", + " step=1,\n", + " value=P\n", + ")\n", + "\n", + "\n", + "# slider L\n", + "slider_L = Slider(\n", + " title=\"Change the length of the beam [m]\",\n", + " start=1,\n", + " end=L,\n", + " step=0.1,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# bracing options\n", + "div_rg_brace_y = Div(text=\"Number of braces in y direction:\")\n", + "radiogroup_brace_y = RadioButtonGroup(labels=['No brace', 'One middle brace', 'Two equally spaced braces'], active=n_bracey)\n", + "div_rg_brace_z = Div(text=\"Number of braces in z direction:\")\n", + "radiogroup_brace_z = RadioButtonGroup(labels=['No brace', 'One middle brace', 'Two equally spaced braces'], active=n_bracez)\n", + "\n", + "\n", + "# figure for buckling\n", + "fig_buckling_y = figure(toolbar_location=None,\n", + " plot_height=FIG_H_S,\n", + " plot_width=FIG_B_S,\n", + " title=\"Beam instability in y direction\",\n", + " x_axis_label=\"Position [m]\",\n", + " x_range = fig_beam.x_range\n", + ")\n", + "fig_buckling_y.ygrid.grid_line_alpha = 0\n", + "fig_buckling_y.yaxis.visible = False\n", + "fig_buckling_y.line('x', 'y', source=source_beam, line_width=1, color='gray')\n", + "mode_shape_y = fig_buckling_y.line(x=[0, L], y=[0, 0], line_width=2, color='black')\n", + "\n", + "fig_buckling_z = figure(toolbar_location=None,\n", + " plot_height=FIG_H_S,\n", + " plot_width=FIG_B_S,\n", + " title=\"Beam instability in z direction\",\n", + " x_axis_label=\"Position [m]\",\n", + " x_range = fig_beam.x_range\n", + ")\n", + "fig_buckling_z.ygrid.grid_line_alpha = 0\n", + "fig_buckling_z.yaxis.visible = False\n", + "fig_buckling_z.line('x', 'y', source=source_beam, line_width=1, color='gray')\n", + "mode_shape_z = fig_buckling_z.line(x=[0, L], y=[0, 0], line_width=2, color='black')\n", + "\n", + "\n", + "# show values of forces \n", + "div_buckling = Div(width=DIV_B_FORCES,\n", + " text=buckling.div_text_buckling(P, Rx, N, \"{:.2f}\".format(Ncrity), \"{:.2f}\".format(Ncritz), \"No\"))\n", + "\n", + "\n", + "# show brace position\n", + "point_brace_y = fig_buckling_y.circle(x=[], y=[], size=10, fill_alpha=0.5, fill_color=\"red\", color=\"red\", alpha=0.5)\n", + "point_brace_z = fig_buckling_z.circle(x=[], y=[], size=10, fill_alpha=0.5, fill_color=\"red\", color=\"red\", alpha=0.5)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_b_h = dict(source=source,\n", + " mode_shape_y=mode_shape_y,\n", + " mode_shape_z=mode_shape_z,\n", + " div=div_geo, \n", + " div_buckling=div_buckling,\n", + " section=section)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const L = db['L'][0]\n", + "const E = db['E'][0]\n", + "const n_bracey = db['n_bracey'][0]\n", + "const n_bracez = db['n_bracez'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const Iz = compute_inertia_z(b, h)\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = Iz\n", + "db['Ncrity'][0] = compute_N_buckling_y(E, Iy, L, n_bracey)\n", + "db['Ncritz'][0] = compute_N_buckling_z(E, Iz, L, n_bracez)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_div_buckling(db, div_buckling)\n", + "update_mode_shape_N_buckling(db, mode_shape_y, mode_shape_z)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{buckling.implement_update_div_bucklingJS()}\n", + "{buckling.implement_compute_N_buckling_yJS()}\n", + "{buckling.implement_compute_N_buckling_zJS()}\n", + "{buckling.implement_compute_mode_shape_N_bucklingJS()}\n", + "{js.implement_linspaceJS()}\n", + "{buckling.implement_update_mode_shape_N_bucklingJS(discr_NVM)}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b_h, code=code_change_b)\n", + "\n", + "\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const h = cb_obj.value // value of the slider\n", + "const b = db['b'][0]\n", + "const L = db['L'][0]\n", + "const E = db['E'][0]\n", + "const n_bracey = db['n_bracey'][0]\n", + "const n_bracez = db['n_bracez'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const Iz = compute_inertia_z(b, h)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = Iz\n", + "db['Ncrity'][0] = compute_N_buckling_y(E, Iy, L, n_bracey)\n", + "db['Ncritz'][0] = compute_N_buckling_z(E, Iz, L, n_bracez)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_div_buckling(db, div_buckling)\n", + "update_mode_shape_N_buckling(db, mode_shape_y, mode_shape_z)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{buckling.implement_update_div_bucklingJS()}\n", + "{buckling.implement_compute_N_buckling_yJS()}\n", + "{buckling.implement_compute_N_buckling_zJS()}\n", + "{buckling.implement_compute_mode_shape_N_bucklingJS()}\n", + "{js.implement_linspaceJS()}\n", + "{buckling.implement_update_mode_shape_N_bucklingJS(discr_NVM)}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_b_h, code=code_change_h)\n", + "\n", + "\n", + "args_slider_L = dict(source=source,\n", + " s_b=source_beam,\n", + " support_r_y=support_r,\n", + " support_r_z=support_r_z,\n", + " axial_force_y=axial_force,\n", + " axial_force_z=axial_force_z,\n", + " label_P_force_y=label_P_force,\n", + " label_P_force_z=label_P_force_z,\n", + " point_brace_y=point_brace_y,\n", + " point_brace_z=point_brace_z,\n", + " mode_shape_y=mode_shape_y,\n", + " mode_shape_z=mode_shape_z,\n", + " div=div_geo,\n", + " div_buckling=div_buckling)\n", + "code_change_L = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const data_b = s_b.data\n", + "const L = cb_obj.value // value of the slider\n", + "const E = db['E'][0]\n", + "const Iy = db['Iy'][0]\n", + "const Iz = db['Iz'][0]\n", + "const n_bracey = db['n_bracey'][0]\n", + "const n_bracez = db['n_bracez'][0]\n", + "\n", + "// apply the changes\n", + "data_b['x'][1] = L\n", + "db['L'][0] = L\n", + "db['Ncrity'][0] = compute_N_buckling_y(E, Iy, L, n_bracey)\n", + "db['Ncritz'][0] = compute_N_buckling_z(E, Iz, L, n_bracez)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_div_buckling(db, div_buckling)\n", + "support_r_y.glyph.x = L\n", + "support_r_z.glyph.x = L\n", + "axial_force_y.x_start = L+{P/SCALE}\n", + "axial_force_y.x_end = L\n", + "label_P_force_y.glyph.x = L+{P/SCALE}/2\n", + "axial_force_z.x_start = L+{P/SCALE}\n", + "axial_force_z.x_end = L\n", + "label_P_force_z.glyph.x = L+{P/SCALE}/2\n", + "update_point_brace(point_brace_y, n_bracey)\n", + "update_point_brace(point_brace_z, n_bracez)\n", + "update_mode_shape_N_buckling(db, mode_shape_y, mode_shape_z)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_b.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{buckling.implement_update_div_bucklingJS()}\n", + "{buckling.implement_compute_N_buckling_yJS()}\n", + "{buckling.implement_compute_N_buckling_zJS()}\n", + "{buckling.implement_update_point_braceJS()}\n", + "{buckling.implement_compute_mode_shape_N_bucklingJS()}\n", + "{js.implement_linspaceJS()}\n", + "{buckling.implement_update_mode_shape_N_bucklingJS(discr_NVM)}\n", + "\"\"\"\n", + "update_L = CustomJS(args=args_slider_L, code=code_change_L)\n", + "\n", + "\n", + "args_slider_P = dict(source=source,\n", + " mode_shape_y=mode_shape_y,\n", + " mode_shape_z=mode_shape_z,\n", + " div_buckling=div_buckling)\n", + "code_slider_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "const db = source.data\n", + "const P = cb_obj.value // value of the slider\n", + "\n", + "// apply the changes\n", + "db['P'][0] = P\n", + "db['N'][0] = compute_N(P)\n", + "db['Rx'][0] = compute_Rx(P)\n", + "\n", + "// update\n", + "update_div_buckling(db, div_buckling)\n", + "update_mode_shape_N_buckling(db, mode_shape_y, mode_shape_z)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_RxJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{buckling.implement_update_div_bucklingJS()}\n", + "{buckling.implement_compute_mode_shape_N_bucklingJS()}\n", + "{js.implement_linspaceJS()}\n", + "{buckling.implement_update_mode_shape_N_bucklingJS(discr_NVM)}\n", + "\"\"\"\n", + "update_P = CustomJS(args=args_slider_P, code=code_slider_P)\n", + "\n", + "\n", + "args_radiogroup_brace_y = dict(source=source,\n", + " mode_shape_y=mode_shape_y,\n", + " mode_shape_z=mode_shape_z,\n", + " div_buckling=div_buckling,\n", + " point_brace=point_brace_y)\n", + "args_radiogroup_brace_z = dict(source=source,\n", + " mode_shape_y=mode_shape_y,\n", + " mode_shape_z=mode_shape_z,\n", + " div_buckling=div_buckling,\n", + " point_brace=point_brace_z)\n", + "code_radiogroup_brace = lambda which_axis : f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const n_brace = cb_obj.active\n", + "const E = db['E'][0]\n", + "const L = db['L'][0]\n", + "const I = db['I{which_axis}'][0]\n", + "\n", + "// apply the changes\n", + "db['n_brace{which_axis}'][0] = n_brace\n", + "db['Ncrit{which_axis}'][0] = compute_N_buckling_{which_axis}(E, I, L, n_brace)\n", + "\n", + "// update\n", + "update_div_buckling(db, div_buckling)\n", + "update_point_brace(point_brace, n_brace)\n", + "update_mode_shape_N_buckling(db, mode_shape_y, mode_shape_z)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{buckling.implement_update_div_bucklingJS()}\n", + "{buckling.implement_compute_N_buckling_yJS()}\n", + "{buckling.implement_compute_N_buckling_zJS()}\n", + "{buckling.implement_update_point_braceJS()}\n", + "{buckling.implement_compute_mode_shape_N_bucklingJS()}\n", + "{js.implement_linspaceJS()}\n", + "{buckling.implement_update_mode_shape_N_bucklingJS(discr_NVM)}\n", + "\"\"\"\n", + "update_brace_y = CustomJS(args=args_radiogroup_brace_y, code=code_radiogroup_brace('y'))\n", + "update_brace_z = CustomJS(args=args_radiogroup_brace_z, code=code_radiogroup_brace('z'))\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_P.js_on_change('value', update_P)\n", + "slider_L.js_on_change('value', update_L)\n", + "radiogroup_brace_y.js_on_click(update_brace_y)\n", + "radiogroup_brace_z.js_on_click(update_brace_z)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the two \"beam instability\" graphs have no y axis (that should show how much the deflection is) because we know only the shape, not the amplitude of the buckling deformation (the constant of integration is set to 1 arbitrarily)." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout),\n", + " slider_b,\n", + " slider_h,\n", + " slider_P,\n", + " slider_L,\n", + " row(div_geo, div_buckling),\n", + " Spacer(height=padding_layout),\n", + " div_rg_brace_y,\n", + " radiogroup_brace_y,\n", + " div_rg_brace_z,\n", + " radiogroup_brace_z))),\n", + " column(Spacer(width=padding_layout)),\n", + " column(fig_beam,\n", + " fig_beam_z,\n", + " fig_buckling_y,\n", + " fig_buckling_z))\n", + " )],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_deflection.ipynb b/Simple Beam DEMOs/sb_deflection.ipynb new file mode 100644 index 0000000..de19ea3 --- /dev/null +++ b/Simple Beam DEMOs/sb_deflection.ipynb @@ -0,0 +1,1171 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Deflection\n", + "In this eigth notebook, the deflection of a simple supported beam is studied." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer, Text\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import stress_strain_elastic as stst\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "q = 4; # [kN/m]\n", + "P = 10; # [kN]\n", + "\n", + "# Choose the material parameters\n", + "E_steel = 200e3 # [MPa] steel\n", + "fy_steel = 355 # [MPa] steel\n", + "E = E_steel\n", + "fy = fy_steel\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "yG = beam_section.compute_centroid_y(h)\n", + "y_n_axis = stst.compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_Q = q/4*5\n", + "SCALE_DEFL = 100\n", + "\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "data_section_scheme = dict(\n", + " x=[0, 0], \n", + " y=[0, h]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " E=[E],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " yG=[yG],\n", + " y_n_axis=[y_n_axis],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " q=[q],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source_section_scheme = ColumnDataSource(data_section_scheme)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 3 - Diagrams):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "DIV_B_GEO = 170\n", + "DIV_B_FORCES = 170\n", + "\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE*SCALE_DEFL, (MAX_Q+OFFSET_Q)/SCALE*SCALE_DEFL)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B*0.8, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(width= DIV_B_GEO, \n", + " text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# uniform load (beam)\n", + "u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE*SCALE_DEFL], width=L, height=q/SCALE*SCALE_DEFL,\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + "label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE*SCALE_DEFL], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2*SCALE_DEFL], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "# CHAGED: moved below for correct display order of glyphs\n", + "# beam_position = fig_beam.circle('x', 'y', **pos_opt) \n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(width=DIV_B_FORCES, \n", + " text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))\n", + "\n", + "\n", + "# figures for the diagrams\n", + "options_diag = dict(\n", + " toolbar_location=None,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_width=FIG_B_B,\n", + " x_range=fig_beam.x_range\n", + ")\n", + "fig_N = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Axial force\", \"@y kN\")],\n", + " y_axis_label=\"Axial force N [kN]\",\n", + " plot_height=int(FIG_H_B*0.8),\n", + " title=\"N V M Diagrams\")\n", + "fig_V = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Shear force\", \"@y kN\")],\n", + " y_axis_label=\"Shear force V [kN]\",\n", + " plot_height=int(FIG_H_B*0.8))\n", + "fig_M = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Bending moment\", \"@y kNm\")],\n", + " y_axis_label=\"Bending moment M [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "fig_N.xaxis.visible = False\n", + "fig_V.xaxis.visible = False\n", + "\n", + "\n", + "# plot N V M\n", + "N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)\n", + "V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)\n", + "M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)\n", + "\n", + "# point that shows the position that it's analyzed\n", + "N_position = fig_N.circle('x', 'N', **pos_opt)\n", + "V_position = fig_V.circle('x', 'V', **pos_opt)\n", + "M_position = fig_M.circle('x', 'M', **pos_opt)\n", + "\n", + "# figures for the stresses and strains\n", + "FIG_B_ss = 200\n", + "FIG_H_ss = 200\n", + "options_stress_strain = dict(\n", + " toolbar_location=None,\n", + " y_axis_label=\"Height h [mm]\",\n", + " plot_width=FIG_B_ss,\n", + " plot_height=FIG_H_ss\n", + ")\n", + "fig_stress_N = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2099 [MPa]\")\n", + "fig_stress_N.yaxis.visible = False\n", + "fig_axial_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2099 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_axial_strain.yaxis.visible = False\n", + "fig_stress_M = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending stress and centroid\",\n", + " y_range=fig_stress_N.y_range,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2098 [MPa]\")\n", + "fig_stress_M.yaxis.visible = False\n", + "fig_bending_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2098 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_bending_strain.yaxis.visible = False\n", + "fig_stress_V = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Shear stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU}\\u1d65 [MPa]\")\n", + "fig_stress_V.yaxis.visible = False\n", + "fig_stress_sigma = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER SIGMA} and neutral axis\",\n", + " y_range=fig_stress_N.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA} [MPa]\")\n", + "fig_stress_tau = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER TAU}\",\n", + " y_range=fig_stress_V.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU} [MPa]\")\n", + "\n", + "# plot stress N V M\n", + "discr_stress_strain = 10\n", + "scale_x = 25\n", + "y_discr = np.linspace(0, h, discr_stress_strain)\n", + "sigma_N = stst.compute_sigma_axial(y_discr, 0, A)\n", + "N_stress_diag = models.stress_diagram(fig_stress_N, sigma_N, h,\n", + " source_section_scheme, scale_x=scale_x/10)\n", + "sigma_M = stst.compute_sigma_bending(y_discr, 0, Iy, yG)\n", + "(M_stress_diag, centroid) = models.stress_diagram(fig_stress_M, sigma_M, h,\n", + " source_section_scheme, True, yG, scale_x=scale_x)\n", + "S_rect = beam_section.compute_first_moment_of_area(y_discr, b, h, yG)\n", + "tau_V = stst.compute_tau_shear(y_discr, 0, S_rect, Iy, b)\n", + "V_stress_diag = models.stress_diagram(fig_stress_V, tau_V, h, source_section_scheme, scale_x=1)\n", + "\n", + "# plot stress sigma and tau\n", + "sigma_total = sigma_M + sigma_N\n", + "(sigma_stress_diag, neutral_axis) = models.stress_diagram(fig_stress_sigma, sigma_total, h,\n", + " source_section_scheme,True, yG, scale_x=scale_x)\n", + "tau_total = tau_V\n", + "tau_stress_diag = models.stress_diagram(fig_stress_tau, tau_total, h,\n", + " source_section_scheme, scale_x=1)\n", + "\n", + "# plot strain N M\n", + "strain_axial = stst.compute_epsilon_axial(y_discr, sigma_N, E)\n", + "axial_strain_diag = models.strain_diagram(fig_axial_strain, strain_axial, h, source_section_scheme)\n", + "strain_bending = stst.compute_epsilon_bending(y_discr, sigma_M, E)\n", + "bending_strain_diag = models.strain_diagram(fig_bending_strain, strain_bending, h, source_section_scheme)\n", + "\n", + "\n", + "# figures for NVM\n", + "fig_NM_section = figure(**options_stress_strain,\n", + " title=\"N and M at position x\",\n", + " match_aspect=True)\n", + "fig_NM_section.axis.visible = False\n", + "fig_NM_section.grid.grid_line_alpha = 0\n", + "\n", + "fig_V_section = figure(**options_stress_strain,\n", + " title=\"V at position x\",\n", + " match_aspect=True)\n", + "fig_V_section.axis.visible = False\n", + "fig_V_section.grid.grid_line_alpha = 0\n", + "\n", + "# section with NVM\n", + "models.section_diagram(fig_NM_section)\n", + "models.section_diagram(fig_V_section)\n", + "\n", + "# NVM in section\n", + "section_N = models.force_vector(fig_NM_section, 0, 0, 0, 0, 0, 'red')\n", + "section_V = models.force_vector(fig_V_section, 0, 0, 0, 0, 0, 'red')\n", + "(section_M_line, section_M_head, source_section_M) = models.define_curvedArrow(fig_NM_section, 0, 0, 0, size_head=0)\n", + "\n", + "# NVM label in section\n", + "OFFSET_N = 1\n", + "label_N_section = fig_NM_section.text(x=[P*1.1], y=[OFFSET_N], text=[\"\"], text_color=\"red\", text_baseline='bottom')\n", + "label_M_section = fig_NM_section.text(x=[OFFSET_N*6], y=[-OFFSET_N*5], text=[\"\"], text_color=\"red\", text_baseline='top')\n", + "label_V_section = fig_V_section.text(x=[OFFSET_N*5], y=[0], text=[\"\"], text_color=\"red\", text_baseline='middle')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# deflection of the beam\n", + "fig_beam.title.text = \"Simple supported beam with deflection under uniform load\"\n", + "fig_beam.ygrid.grid_line_alpha = 1\n", + "fig_beam.yaxis.visible = True\n", + "fig_beam.yaxis.axis_label = \"Deflection [mm]\"\n", + "\n", + "\n", + "# line 70-76 removed: uniform load (beam) and axial force (beam) in the simple beam\n", + "\n", + "\n", + "# Change the beam in the beam figure to gray and line width smaller and add new line\n", + "beam.glyph.line_width = 1\n", + "beam.glyph.line_color = \"gray\"\n", + "beam_defl = fig_beam.line(x=x_discr,\n", + " y=sb.compute_deflection_uniform_load(x_discr, q, L, Iy, E),\n", + " line_width=6, color='black')\n", + "\n", + "# FROM ABOVE: position point\n", + "beam_position = fig_beam.circle('x', 'y', **pos_opt)\n", + "\n", + "\n", + "# choose different elastic modulus\n", + "E_wood = 8e3 # [MPa]\n", + "E_concrete = 26e3 # [MPa]\n", + "E_ceramic = 300e3 # [MPa]\n", + "slider_elastic = Slider(\n", + " title=\"Change the elastic modulus [MPa]\",\n", + " start=E_wood,\n", + " end=E_ceramic,\n", + " step=1e3,\n", + " value=E,\n", + " margin=(5, 5, 0, 5)\n", + ")\n", + "\n", + "\n", + "# show values of E\n", + "div_E = Div(margin=(0, 5, 0, 5),\n", + " text=f\"\"\"\n", + "

\n", + " Ewood = {math.trunc(E_wood/1e3)} GPa; Econcrete = {math.trunc(E_concrete/1e3)} GPa
\n", + " Esteel = {math.trunc(E_steel/1e3)} GPa; Eceramic = {math.trunc(E_ceramic/1e3)} GPa

\n", + " \"\"\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update data\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{models.implement_check_stateJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b = dict(source=source,\n", + " s_b=source_beam,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " beam_defl=beam_defl)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const yG = db['yG'][0]\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_deflection_beam(db, beam_defl)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_deflection_beamJS(discr_NVM)}\n", + "{sb.implement_compute_deflection_uniform_loadJS()}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b, code=code_change_b)\n", + "\n", + "\n", + "args_slider_h = dict(source=source,\n", + " s_b=source_beam,\n", + " s_ss=source_section_scheme,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " beam_defl=beam_defl)\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const data_ss = s_ss.data\n", + "const b = db['b'][0]\n", + "const h = cb_obj.value // value of the slider\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "const yG = compute_centroid_y(h)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['yG'][0] = yG\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "data_ss['y'][1] = h // change the height of the section in the diagrams\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_deflection_beam(db, beam_defl)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_ss.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{js.implement_update_deflection_beamJS(discr_NVM)}\n", + "{sb.implement_compute_deflection_uniform_loadJS()}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head,\n", + " N_diag=N_diag,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "\n", + "// apply the changes\n", + "db['P'][0] = {P}*(1-f)\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_N_diagram(db, N_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_N_diagramJS(discr_NVM)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " V_diag=V_diag,\n", + " M_diag=M_diag,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " beam_defl=beam_defl)\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['q'][0] = q\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_V_diagram(db, V_diag)\n", + "update_M_diagram(db, M_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "update_deflection_beam(db, beam_defl)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_update_V_diagramJS(discr_NVM)}\n", + "{sb.implement_update_M_diagramJS(discr_NVM)}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_deflection_beamJS(discr_NVM)}\n", + "{sb.implement_compute_deflection_uniform_loadJS()}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "\n", + "args_slider_elastic = dict(source=source,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " centroid=centroid,\n", + " beam_defl=beam_defl)\n", + "# code_slider_elastic = \"\"\n", + "code_slider_elastic = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const E = cb_obj.value\n", + "\n", + "// update E\n", + "db['E'][0] = E\n", + "\n", + "// update\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_deflection_beam(db, beam_defl)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_linspaceJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{js.implement_update_deflection_beamJS(discr_NVM)}\n", + "{sb.implement_compute_deflection_uniform_loadJS()}\n", + "\"\"\"\n", + "update_slider_elastic = CustomJS(args=args_slider_elastic, code=code_slider_elastic)\n", + "\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)\n", + "slider_elastic.js_on_change('value', update_slider_elastic)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_scheme,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout*3),\n", + " slider_b,\n", + " slider_h,\n", + " slider_position,\n", + " slider_q,\n", + " slider_elastic,\n", + " div_E,\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P))),\n", + " column(fig_beam,\n", + " Spacer(height=padding_layout),\n", + " fig_N,\n", + " fig_V,\n", + " fig_M)),\n", + " row(column(\n", + " row(fig_NM_section, fig_axial_strain, fig_stress_N, fig_bending_strain, fig_stress_M, fig_stress_sigma),\n", + " row(fig_V_section, Spacer(width=FIG_B_ss), fig_stress_V, Spacer(width=FIG_B_ss), Spacer(width=FIG_B_ss), fig_stress_tau),\n", + " ))\n", + " ),\n", + " ],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_diagrams.ipynb b/Simple Beam DEMOs/sb_diagrams.ipynb new file mode 100644 index 0000000..7ea7c61 --- /dev/null +++ b/Simple Beam DEMOs/sb_diagrams.ipynb @@ -0,0 +1,743 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Diagrams\n", + "In this third notebook, the axial N, shear V and bending moment M diagrams are presented. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer, Text\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "q = 4; # [kN/m]\n", + "P = 10; # [kN]\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_Q = q/4*5\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " q=[q],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 2 - Actions):" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# Darth Vader for scale (if not visualized, remove this part because the browser don't support it correctly)\n", + "h_img = 300 # mm\n", + "fig_section.image_url(url=['https://cdn.popcultcha.com.au/media/catalog/product/cache/207e23213cf636ccdef205098cf3c8a3/s/t/star-wars-darth-vader-premium-electronic-helmet-black-series-replica-hasbro-popcultcha.png'], x=-h_img/2, y=-MAX_H/2*1.05, h=h_img, w=h_img/681*700)\n", + "fig_section.text(x=[0], y=[-MAX_H/2-h_img*1.15], text_align=\"center\", text=[f\"Darth Vader's helmet for scale (h={h_img} mm)\"], text_font_size=\"10px\")\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# uniform load (beam)\n", + "u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE], width=L, height=q/SCALE,\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + "label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "beam_position = fig_beam.circle('x', 'y', **pos_opt)\n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# figures for the diagrams\n", + "options_diag = dict(\n", + " toolbar_location=None,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_width=FIG_B_B,\n", + " x_range=fig_beam.x_range\n", + ")\n", + "fig_N = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Axial force\", \"@y kN\")],\n", + " y_axis_label=\"Axial force N [kN]\",\n", + " plot_height=int(FIG_H_B*0.8),\n", + " title=\"N V M Diagrams\")\n", + "fig_V = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Shear force\", \"@y kN\")],\n", + " y_axis_label=\"Shear force V [kN]\",\n", + " plot_height=int(FIG_H_B*0.8))\n", + "fig_M = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Bending moment\", \"@y kNm\")],\n", + " y_axis_label=\"Bending moment M [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "fig_N.xaxis.visible = False\n", + "fig_V.xaxis.visible = False\n", + "\n", + "\n", + "# plot N V M\n", + "N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)\n", + "V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)\n", + "M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)\n", + "\n", + "# point that shows the position that it's analyzed\n", + "N_position = fig_N.circle('x', 'N', **pos_opt)\n", + "V_position = fig_V.circle('x', 'V', **pos_opt)\n", + "M_position = fig_M.circle('x', 'M', **pos_opt)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head)\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update data\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{models.implement_check_stateJS()}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b_h = dict(source=source,\n", + " s_b=source_beam,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b_h, code=code_change_b)\n", + "\n", + "\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = db['b'][0]\n", + "const h = cb_obj.value // value of the slider\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_b_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head,\n", + " N_diag=N_diag)\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "\n", + "// apply the changes\n", + "db['P'][0] = {P}*(1-f)\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_N_diagram(db, N_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_N_diagramJS(discr_NVM)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " V_diag=V_diag,\n", + " M_diag=M_diag)\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['q'][0] = q\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_V_diagram(db, V_diag)\n", + "update_M_diagram(db, M_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_update_V_diagramJS(discr_NVM)}\n", + "{sb.implement_update_M_diagramJS(discr_NVM)}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_scheme,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout),\n", + " slider_b,\n", + " slider_h,\n", + " div_geo,\n", + " Spacer(height=padding_layout),\n", + " slider_position,\n", + " slider_q,\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P))),\n", + " column(fig_beam,\n", + " Spacer(height=padding_layout),\n", + " fig_N,\n", + " fig_V,\n", + " fig_M,\n", + " div_forces))\n", + " )],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_geo.ipynb b/Simple Beam DEMOs/sb_geo.ipynb new file mode 100644 index 0000000..918071e --- /dev/null +++ b/Simple Beam DEMOs/sb_geo.ipynb @@ -0,0 +1,369 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Geometry\n", + "In this first notebook, the geometry of a simple beam with rectangular section is explored. The correlated mechanical parameters are also visualized." + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer\n", + "from bokeh.models.tickers import SingleIntervalTicker\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import models\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry:" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "\n", + "# constants for the visualisation\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "initial_position = L\n", + "data = dict( # stores every useful single variable\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " x=[initial_position],\n", + " y=[0]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
GlyphRenderer(
id = '11046', …)
coordinates = None,
data_source = ColumnDataSource(id='11042', ...),
glyph = Text(id='11043', ...),
group = None,
hover_glyph = None,
js_event_callbacks = {},
js_property_callbacks = {},
level = 'glyph',
muted = False,
muted_glyph = Text(id='11045', ...),
name = None,
nonselection_glyph = Text(id='11044', ...),
selection_glyph = 'auto',
subscribed_events = [],
syncable = True,
tags = [],
view = CDSView(id='11047', ...),
visible = True,
x_range_name = 'default',
y_range_name = 'default')
\n", + "\n" + ], + "text/plain": [ + "GlyphRenderer(id='11046', ...)" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_SEC = 600 # height figure section\n", + "\n", + "paddingx = 0.2*L\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "fig_beam = figure(**options,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_height=200,\n", + " plot_width=700,\n", + " x_range=(0-paddingx, L+paddingx),\n", + " y_range=(-1, 1),\n", + " title=\"Simple supported beam\"\n", + ")\n", + "fig_beam.xgrid.grid_line_alpha = 0\n", + "fig_beam.ygrid.grid_line_alpha = 0\n", + "fig_beam.yaxis.visible = False\n", + "\n", + "fig_section = figure(**options,\n", + " x_axis_label=\"Width b [mm]\",\n", + " y_axis_label=\"Height h [mm]\",\n", + " plot_height=int(MAX_H*0.9),\n", + " plot_width=int(MAX_B),\n", + " match_aspect=True,\n", + " title=\"Cross-section of the beam\"\n", + ")\n", + "fig_section.rect([0], [0], width=MAX_B, height=MAX_H, alpha=0, fill_alpha=0) # transparent rect\n", + "fig_section.axis.ticker = SingleIntervalTicker(interval=50, num_minor_ticks=5)\n", + "\n", + "\n", + "# Helmet for scale (if not visualized, remove this part because the browser don't support it correctly)\n", + "h_img = 110 # mm\n", + "fig_section.image_url(url=['https://www.planen-boehme.de/images/zollstock2.png?crc=3862361968'], x=-h_img/2*2, y=-MAX_H/2*1.01, h=h_img, w=h_img*2)\n", + "# fig_section.image_url(url=['https://www.lotarpersiane.it/wp-content/uploads/2022/01/metro-e1642585741507.png'], x=-h_img/2*2, y=-MAX_H/2*1.01, h=h_img, w=h_img*2)\n", + "# fig_section.image_url(url=['https://www.massstab-diamant.de/media/pages/massstaebe/carat/89cd9b8591-1604663572/gelb-carat-960x480-crop-1-q90.png'], x=-h_img/2*2, y=-MAX_H/2*1.01, h=h_img, w=h_img*2)\n", + "fig_section.text(x=[0], y=[-MAX_H/2-h_img*1.3], text_align=\"center\", text=[f\"Carpenter's ruler for scale (h={h_img} mm)\"], text_font_size=\"10px\")\n", + "\n", + "\n", + "# beam\n", + "beam = fig_beam.line('x', 'y', source=source_beam, line_width=6, color='black')\n", + "b_supp = 0.3\n", + "supp_opt = dict(\n", + " fill_color='white',\n", + " line_color='black'\n", + ")\n", + "support_l = fig_beam.patch([0, b_supp/2, -b_supp/2],\n", + " [0, -b_supp/2*math.sqrt(3), -b_supp/2*math.sqrt(3)],\n", + " **supp_opt)\n", + "support_r = fig_beam.circle([L], [-b_supp/2], radius=b_supp/2, **supp_opt)\n", + "\n", + "\n", + "# section\n", + "section = fig_section.rect([0], [0], width=b, height=h, fill_color='white',\n", + " color='black', line_width=3, hatch_pattern='/', hatch_color='black')\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_text = lambda h, b, L, A, Iy, Iz : f\"\"\"

Geometrical and mechanical parameters:

\n", + " h = {round(h)} mm
\n", + " b = {round(b)} mm
\n", + " L = {round(L)} m
\n", + " A = {\"{:.2e}\".format(A)} mm2
\n", + " Iy = {\"{:.2e}\".format(Iy)} mm4
\n", + " Iz = {\"{:.2e}\".format(Iz)} mm4\"\"\"\n", + "\n", + "div = Div(\n", + " text=div_text(h, b, L, A, Iy, Iz),\n", + " width=300,\n", + " height=300\n", + ")\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "slider_L = Slider(\n", + " title=\"Change the length L [m]\",\n", + " start=1,\n", + " end=L+1,\n", + " step=0.1,\n", + " value=L\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "x_axis_arrow = models.force_vector(fig_beam, axis_arrow_length, L, L+axis_arrow_length, 0, 0, 'gray')\n", + "x_axis_label = fig_beam.text(x=[L+axis_arrow_length/2], y=[0.1], text=[\"x axis\"], text_color='gray', text_baseline='bottom')\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y axis\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z axis\"], text_color='gray', text_align='right', text_baseline='middle')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "code_slider = lambda var, L_code, b_code, h_code, x_axis_code=\"\" : f\"\"\"\n", + " // retrieve data used\n", + " const data_b = s_b.data\n", + " const data_s = s_s.data\n", + " // retrieve the var from the object that uses callback\n", + " const f = cb_obj.value // value of the slider\n", + " // compute the parameters and dimensions\n", + " const L = Math.round({L_code}*10)/10\n", + " const b = Math.round({b_code})\n", + " const h = Math.round({h_code})\n", + " const A = b*h\n", + " const Iy = Math.round(Math.pow(h, 3)*b/12)\n", + " const Iz = Math.round(Math.pow(b, 3)*h/12)\n", + " div.text = \"

Geometrical and mechanical parameters:

h = \"+h+\n", + " \" mm
b = \"+b+\n", + " \" mm
L = \"+L+\n", + " \" m
A = \"+A.toExponential()+\n", + " \" mm2
Iy = \"+Iy.toExponential()+\n", + " \" mm4
Iz = \"+Iz.toExponential()+\n", + " \" mm4\"\n", + " // change the plot of the section\n", + " section.glyph.width = b\n", + " section.glyph.height = h\n", + " // change the plot of the beam\n", + " data_b['x'][1] = L\n", + " support_r.glyph.x = L\n", + " {x_axis_code}\n", + " // apply the changes\n", + " data_s['{var}'] = f\n", + " data_s['A'] = A\n", + " data_s['Iy'] = Iy\n", + " data_s['Iz'] = Iz\n", + " s_s.change.emit()\n", + " s_b.change.emit()\n", + "\"\"\"\n", + "\n", + "x_axis_code = f\"\"\"\n", + "// change the position of the x axis arrow and text\n", + "x_axis_arrow.x_start = L\n", + "x_axis_arrow.x_end = L+{axis_arrow_length}\n", + "x_axis_label.glyph.x = L+{axis_arrow_length}/2\n", + "\"\"\"\n", + "\n", + "# logic for slider_L\n", + "update_L = CustomJS(args=dict(s_b=source_beam, s_s=source, div=div, section=section, support_r=support_r,\n", + " x_axis_arrow=x_axis_arrow, x_axis_label=x_axis_label),\n", + " code=code_slider(\"L\", \"f\", \"data_s['b']\", \"data_s['h']\", x_axis_code))\n", + "\n", + "slider_L.js_on_change('value', update_L)\n", + "\n", + "# logic for slider_b\n", + "update_b = CustomJS(args=dict(s_b=source_beam, s_s=source, div=div, section=section, support_r=support_r),\n", + " code=code_slider(\"b\", \"data_s['L']\", \"f\", \"data_s['h']\"))\n", + "\n", + "slider_b.js_on_change('value', update_b)\n", + "\n", + "# logic for slider_h\n", + "update_h = CustomJS(args=dict(s_b=source_beam, s_s=source, div=div, section=section, support_r=support_r),\n", + " code=code_slider(\"h\", \"data_s['L']\", \"data_s['b']\", \"f\"))\n", + "\n", + "slider_h.js_on_change('value', update_h)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + } + ], + "source": [ + "layout1 = layout([\n", + " [fig_beam],\n", + " [fig_section, Spacer(width=20), column([Spacer(height=50), slider_L, slider_b, slider_h, Spacer(height=50), div])] \n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_mohr.ipynb b/Simple Beam DEMOs/sb_mohr.ipynb new file mode 100644 index 0000000..2c37e1a --- /dev/null +++ b/Simple Beam DEMOs/sb_mohr.ipynb @@ -0,0 +1,1861 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Mohr Circle\n", + "In this first notebook, the Mohr circle is presented." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource, output_file, save\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import stress_strain_elastic as stst\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "from cienpy import mohrcircle\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "q = 4; # [kN/m]\n", + "P = 10; # [kN]\n", + "\n", + "# Choose the material parameters\n", + "E = 200e3 # [MPa]\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "yG = beam_section.compute_centroid_y(h)\n", + "y_n_axis = stst.compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "# compute Mohr circle parameters\n", + "initial_y = h\n", + "initial_theta_element = 0\n", + "sigma_axial = stst.compute_sigma_axial(initial_y, N, A)\n", + "sigma_bending = stst.compute_sigma_bending(initial_y, M, Iy, yG)\n", + "S = beam_section. compute_first_moment_of_area(initial_y, b, h, yG)\n", + "sigma_tau = stst.compute_tau_shear(initial_y, V, S, Iy, b)\n", + "sigma_x0 = stst.compute_total_sigma(sigma_axial, sigma_bending)\n", + "sigma_y0 = 0 # no vertical axial forces\n", + "tau_0 = stst.compute_total_tau(sigma_tau)\n", + "sigma_average_mohr = mohrcircle.compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "r_circle_mohr = mohrcircle.compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "theta_principal = mohrcircle.compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "initial_theta = mohrcircle.compute_theta_mohr(initial_theta_element, theta_principal)\n", + "\n", + "# stress state in function of theta\n", + "new_state = mohrcircle.compute_stress_state_mohr(sigma_average_mohr, r_circle_mohr, initial_theta)\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 2*b\n", + "MAX_H = 2*h\n", + "MAX_Q = q/4*5\n", + "MAX_STRESS = 60\n", + "MAX_STRESS_MOHR = 10\n", + "MAX_DIM_STRESS_STATE = MAX_STRESS*2.5\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "data_section_scheme = dict(\n", + " x=[0, 0], \n", + " y=[0, h]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " E=[E],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " yG=[yG],\n", + " y_n_axis=[y_n_axis],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " y_var=[initial_y],\n", + " theta_element=[initial_theta_element], # rad\n", + " theta=[initial_theta], # rad\n", + " sigma_x0=[sigma_x0],\n", + " sigma_y0=[sigma_y0],\n", + " tau_0=[tau_0],\n", + " sigma_average=[sigma_average_mohr],\n", + " r_circle_mohr=[r_circle_mohr],\n", + " sigma_x=[new_state[0]],\n", + " sigma_y=[new_state[1]],\n", + " tau=[new_state[2]],\n", + " q=[q],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source_section_scheme = ColumnDataSource(data_section_scheme)\n", + "source = ColumnDataSource(data)\n", + "\n", + "# Constants\n", + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 600 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 500 # height figure section\n", + "DIV_B_GEO = 170\n", + "DIV_B_FORCES = 170\n", + "FIG_MOHR = 600\n", + "FIG_STRESS_STATE = 600" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 3 - Diagrams):" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "\n", + "\n", + "######################## Start modifications\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-MAX_H*0.2, MAX_H*1.4)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "# modify beam \n", + "#TODO: add to cienpy\n", + "def draw_beam_2D(fig, L: float, h: float, b_supp=0.25, ratio = 1.0):\n", + " \"\"\"\n", + " Function that draws the simple beam in a figure.\n", + "\n", + " @param fig (bokeh.plotting.figure.Figure): Figure that will be the canvas for the plot.\n", + " @param src (bokeh.models.sources.ColumnDataSource): Source of the coordinates.\n", + " @param L (float): Length of the beam in m.\n", + " @param x (str): Key for the x values. Defaults to 'x'.\n", + " @param y (str): Key for the y values. Defaults to 'y'.\n", + " @param b_supp (float, optional): Size of the supports in x. Defaults to 0.3.\n", + " @param ratio (float, optional): Ratio of the figure (interval_y/height*100). Defaults to 1.0 (axis equal).\n", + " \n", + " @return tuple: Tuple with the renderers of the beam and supports.\n", + " \"\"\"\n", + " beam = fig.rect([L/2], [h/2], width=L, height=h, \n", + " fill_color='lightgray', color='black', line_width=1)\n", + " supp_opt = dict(\n", + " fill_color='white',\n", + " line_color='black'\n", + " )\n", + " support_l = models.define_pinned(fig, 0, 0, b_supp, ratio, supp_opt)\n", + " support_r = models.define_roller(fig, L, 0, b_supp, ratio, supp_opt)\n", + " \n", + " return (beam, support_l, support_r)\n", + "\n", + "(beam, support_l, support_r) = draw_beam_2D(fig_beam, L, h,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# uniform load (beam)\n", + "if q!=0:\n", + " fig_beam.rect([L/2], [(int_y_b[1]+MAX_H)/2], width=L, height=(0.99*(int_y_b[1]-MAX_H)),\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + " fig_beam.text(x=[-0.2], y=[MAX_H], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "####################### End modification\n", + "\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B*0.8, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(width= DIV_B_GEO, \n", + " text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(width=DIV_B_FORCES, \n", + " text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))\n", + "\n", + "\n", + "# figures for the diagrams\n", + "options_diag = dict(\n", + " toolbar_location=None,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_width=FIG_B_B,\n", + " x_range=fig_beam.x_range\n", + ")\n", + "fig_N = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Axial force\", \"@y kN\")],\n", + " y_axis_label=\"Axial force N [kN]\",\n", + " plot_height=int(FIG_H_B*0.8),\n", + " title=\"N V M Diagrams\")\n", + "fig_V = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Shear force\", \"@y kN\")],\n", + " y_axis_label=\"Shear force V [kN]\",\n", + " plot_height=int(FIG_H_B*0.8))\n", + "fig_M = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Bending moment\", \"@y kNm\")],\n", + " y_axis_label=\"Bending moment M [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "fig_N.xaxis.visible = False\n", + "fig_V.xaxis.visible = False\n", + "\n", + "\n", + "# plot N V M\n", + "N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)\n", + "V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)\n", + "M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)\n", + "\n", + "# point that shows the position that it's analyzed\n", + "N_position = fig_N.circle('x', 'N', **pos_opt)\n", + "V_position = fig_V.circle('x', 'V', **pos_opt)\n", + "M_position = fig_M.circle('x', 'M', **pos_opt)\n", + "\n", + "\n", + "# figures for the stresses and strains\n", + "FIG_B_ss = 200\n", + "FIG_H_ss = 200\n", + "options_stress_strain = dict(\n", + " toolbar_location=None,\n", + " y_axis_label=\"Height h [mm]\",\n", + " plot_width=FIG_B_ss,\n", + " plot_height=FIG_H_ss\n", + ")\n", + "fig_stress_N = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2099 [MPa]\")\n", + "fig_stress_N.yaxis.visible = False\n", + "fig_axial_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2099 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_axial_strain.yaxis.visible = False\n", + "fig_stress_M = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending stress and centroid\",\n", + " y_range=fig_stress_N.y_range,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2098 [MPa]\")\n", + "fig_stress_M.yaxis.visible = False\n", + "fig_bending_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2098 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_bending_strain.yaxis.visible = False\n", + "fig_stress_V = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Shear stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU}\\u1d65 [MPa]\")\n", + "fig_stress_V.yaxis.visible = False\n", + "fig_stress_sigma = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER SIGMA} and neutral axis\",\n", + " y_range=fig_stress_N.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA} [MPa]\")\n", + "fig_stress_tau = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER TAU}\",\n", + " y_range=fig_stress_V.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU} [MPa]\")\n", + "\n", + "# plot stress N V M\n", + "discr_stress_strain = 10\n", + "scale_x = 25\n", + "y_discr = np.linspace(0, h, discr_stress_strain)\n", + "sigma_N = stst.compute_sigma_axial(y_discr, 0, A)\n", + "N_stress_diag = models.stress_diagram(fig_stress_N, sigma_N, h,\n", + " source_section_scheme, scale_x=scale_x/10)\n", + "sigma_M = stst.compute_sigma_bending(y_discr, 0, Iy, yG)\n", + "(M_stress_diag, centroid) = models.stress_diagram(fig_stress_M, sigma_M, h,\n", + " source_section_scheme, True, yG, scale_x=scale_x)\n", + "S_rect = beam_section.compute_first_moment_of_area(y_discr, b, h, yG)\n", + "tau_V = stst.compute_tau_shear(y_discr, 0, S_rect, Iy, b)\n", + "V_stress_diag = models.stress_diagram(fig_stress_V, tau_V, h, source_section_scheme, scale_x=1)\n", + "\n", + "# plot stress sigma and tau\n", + "sigma_total = sigma_M + sigma_N\n", + "(sigma_stress_diag, neutral_axis) = models.stress_diagram(fig_stress_sigma, sigma_total, h,\n", + " source_section_scheme,True, yG, scale_x=scale_x)\n", + "tau_total = tau_V\n", + "tau_stress_diag = models.stress_diagram(fig_stress_tau, tau_total, h,\n", + " source_section_scheme, scale_x=1)\n", + "\n", + "# plot strain N M\n", + "strain_axial = stst.compute_epsilon_axial(y_discr, sigma_N, E)\n", + "axial_strain_diag = models.strain_diagram(fig_axial_strain, strain_axial, h, source_section_scheme)\n", + "strain_bending = stst.compute_epsilon_bending(y_discr, sigma_M, E)\n", + "bending_strain_diag = models.strain_diagram(fig_bending_strain, strain_bending, h, source_section_scheme)\n", + "\n", + "\n", + "# figures for NVM\n", + "fig_NM_section = figure(**options_stress_strain,\n", + " title=\"N and M at position x\",\n", + " match_aspect=True)\n", + "fig_NM_section.axis.visible = False\n", + "fig_NM_section.grid.grid_line_alpha = 0\n", + "\n", + "fig_V_section = figure(**options_stress_strain,\n", + " title=\"V at position x\",\n", + " match_aspect=True)\n", + "fig_V_section.axis.visible = False\n", + "fig_V_section.grid.grid_line_alpha = 0\n", + "\n", + "# section with NVM\n", + "models.section_diagram(fig_NM_section)\n", + "models.section_diagram(fig_V_section)\n", + "\n", + "# NVM in section\n", + "section_N = models.force_vector(fig_NM_section, 0, 0, 0, 0, 0, 'red')\n", + "section_V = models.force_vector(fig_V_section, 0, 0, 0, 0, 0, 'red')\n", + "(section_M_line, section_M_head, source_section_M) = models.define_curvedArrow(fig_NM_section, 0, 0, 0, size_head=0)\n", + "\n", + "# NVM label in section\n", + "OFFSET_N = 1\n", + "label_N_section = fig_NM_section.text(x=[P*1.1], y=[OFFSET_N], text=[\"\"], text_color=\"red\", text_baseline='bottom')\n", + "label_M_section = fig_NM_section.text(x=[OFFSET_N*6], y=[-OFFSET_N*5], text=[\"\"], text_color=\"red\", text_baseline='top')\n", + "label_V_section = fig_V_section.text(x=[OFFSET_N*5], y=[0], text=[\"\"], text_color=\"red\", text_baseline='middle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "SCALE_TAU = 5\n", + "\n", + "# Modify the beam figure and plots (see in the previous code cell)\n", + "\n", + "\n", + "# Modifiy focus point to square in beam\n", + "beam_position = fig_beam.square('x', 'y_var', **pos_opt)\n", + "\n", + "\n", + "# choose height of interest\n", + "slider_y = Slider(\n", + " title=\"Change the height y along the section [mm]\",\n", + " start=0,\n", + " end=h,\n", + " step=1,\n", + " value=initial_y\n", + ")\n", + "\n", + "\n", + "# choose angle theta of interest\n", + "slider_theta_element = Slider(\n", + " title=\"Change the angle \\N{GREEK SMALL LETTER THETA} of the element [°]\",\n", + " start=0,\n", + " end=90,\n", + " step=0.5,\n", + " value=initial_theta_element\n", + ")\n", + "\n", + "\n", + "# figure Mohr circle\n", + "fig_Mohr_circle = figure(toolbar_location=None,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA} [MPa]\",\n", + " y_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU} [MPa]\",\n", + " plot_height=FIG_MOHR,\n", + " plot_width=FIG_MOHR,\n", + " match_aspect=True,\n", + " # x_range=[-MAX_STRESS_MOHR, MAX_STRESS_MOHR],\n", + " title=\"Mohr circle, x axis: stress \\N{GREEK SMALL LETTER SIGMA} [MPa], y axis: stress \\N{GREEK SMALL LETTER TAU} [MPa]\"\n", + ")\n", + "fig_Mohr_circle.axis.fixed_location = 0\n", + "\n", + "\n", + "# figure stress state element\n", + "fig_stress_state = figure(toolbar_location=None,\n", + " plot_height=FIG_STRESS_STATE,\n", + " plot_width=FIG_STRESS_STATE,\n", + " match_aspect=True,\n", + " title=\"Stress state\"\n", + ")\n", + "fig_stress_state.grid.grid_line_alpha = 0\n", + "fig_stress_state.axis.visible = False\n", + "fig_stress_state.min_border_left = 0\n", + "fig_stress_state.rect([MAX_DIM_STRESS_STATE*0.4], [MAX_DIM_STRESS_STATE*0.4],\n", + " width=MAX_DIM_STRESS_STATE*1.2,\n", + " height=MAX_DIM_STRESS_STATE*1.2,\n", + " alpha=0,\n", + " fill_alpha=0)\n", + "\n", + "\n", + "# stress state (theta 0)\n", + "fig_stress_state.rect([0], [0],\n", + " width=MAX_STRESS/2,\n", + " height=MAX_STRESS/2,\n", + " angle=0,\n", + " fill_alpha=0, color='black', line_width=2)\n", + "fig_stress_state.text([0], [0],\n", + " text=[\"Fixed \\nelement\"],\n", + " text_align=\"center\", text_baseline=\"middle\",\n", + " text_font_size=\"14px\")\n", + "\n", + "\n", + "# stress state variable\n", + "stress_state_theta = fig_stress_state.rect([MAX_STRESS*2], [0],\n", + " width=MAX_STRESS/2,\n", + " height=MAX_STRESS/2,\n", + " angle=initial_theta_element, \n", + " fill_alpha=0, color='black', line_width=2)\n", + "label_stress_state_theta = fig_stress_state.text([MAX_STRESS*2], [0],\n", + " text=[\"Rotating \\nelement\"],\n", + " text_align=\"center\", text_baseline=\"middle\",\n", + " text_font_size=\"14px\")\n", + "\n", + "# rotating axis\n", + "rotating_axis = fig_stress_state.line([0, MAX_DIM_STRESS_STATE], [0, 0],\n", + " line_dash=\"4 4\", line_color=\"black\", line_width=0.5)\n", + "\n", + "\n", + "# arc and label theta in stress state\n", + "arc_theta_element = fig_stress_state.arc(x=[0], y=[0],\n", + " radius=MAX_STRESS, start_angle=0, end_angle=0,\n", + " line_color=\"gray\", line_dash=\"2 5\")\n", + "label_theta_element = fig_stress_state.text([MAX_STRESS], [0],\n", + " text=[\"\"],\n", + " text_baseline=\"middle\", x_offset=5, text_font_size=\"14px\")\n", + "\n", + "# fixed axis\n", + "fig_stress_state.line([0, MAX_DIM_STRESS_STATE], [0, 0],\n", + " line_dash=\"4 4\", line_color=\"black\", line_width=0.5)\n", + "\n", + "\n", + "# stress state arrows\n", + "arrows_stress_state = models.set_arrows_stress_state(fig_stress_state, sigma_x0, sigma_y0, tau_0, MAX_STRESS/2,\n", + " SCALE_TAU)\n", + "\n", + "\n", + "# stress state theta arrows \n", + "arrows_stress_state_theta = models.set_arrows_stress_state(fig_stress_state, sigma_x0, sigma_y0, tau_0, MAX_STRESS/2,\n", + " SCALE_TAU, MAX_STRESS*2)\n", + "\n", + "# Mohr circle\n", + "Mohr_circle = fig_Mohr_circle.circle([sigma_average_mohr], [0],\n", + " radius=r_circle_mohr,\n", + " fill_alpha=0, color=\"gray\")\n", + "\n", + "\n", + "# arc and label theta in Mohr circle\n", + "arc_theta_Mohr = fig_Mohr_circle.arc(x=[sigma_average_mohr], y=[0],\n", + " radius=r_circle_mohr/2, start_angle=0, end_angle=0,\n", + " line_color=\"gray\", line_dash=\"2 5\")\n", + "label_theta_Mohr = fig_Mohr_circle.text([sigma_average_mohr+r_circle_mohr/2], [0],\n", + " text=[\"\"],\n", + " text_baseline=\"middle\", x_offset=5, text_font_size=\"14px\")\n", + "arc_theta_p_Mohr = fig_Mohr_circle.arc(x=[sigma_average_mohr], y=[0],\n", + " radius=r_circle_mohr/2, start_angle=0, end_angle=0,\n", + " line_color=\"gray\", line_dash=\"2 5\")\n", + "label_theta_p_Mohr = fig_Mohr_circle.text([sigma_average_mohr+r_circle_mohr/5*2], [0],\n", + " text=[\"\"],\n", + " text_baseline=\"middle\", x_offset=5, text_font_size=\"14px\")\n", + "\n", + "\n", + "# linking line and two points from current stress state\n", + "mohr_points_opt = dict(\n", + " size=5,\n", + " fill_alpha=0.5,\n", + " alpha=0.5\n", + ")\n", + "line_stress_state = fig_Mohr_circle.line([sigma_x0, tau_0], [sigma_y0, -tau_0],\n", + " line_dash=\"4 4\", line_color=\"blue\", line_width=0.5)\n", + "points_stress_state = fig_Mohr_circle.circle([sigma_x0, tau_0], [sigma_y0, -tau_0],\n", + " **mohr_points_opt, color=\"blue\", fill_color=\"blue\")\n", + "str_label_stress_state1 = \"Fixed element \\n(\\N{GREEK SMALL LETTER SIGMA}\\N{LATIN SUBSCRIPT SMALL LETTER X}\\N{SUBSCRIPT ZERO}, \\N{GREEK SMALL LETTER TAU}\\N{SUBSCRIPT ZERO})\"\n", + "# NB: no subscript of latin y, so use gamma (very similar in the display)\n", + "str_label_stress_state2 = \"Fixed element \\n(\\N{GREEK SMALL LETTER SIGMA}\\N{Greek Subscript Small Letter Gamma}\\N{SUBSCRIPT ZERO}, -\\N{GREEK SMALL LETTER TAU}\\N{SUBSCRIPT ZERO})\"\n", + "label_points_stress_state = fig_Mohr_circle.text([sigma_x0, tau_0], [sigma_y0, -tau_0],\n", + " text=[str_label_stress_state1, str_label_stress_state2],\n", + " color=\"blue\", x_offset=5, y_offset=18, text_font_size=\"14px\")\n", + "\n", + "\n", + "# linking line and two points from stress state in function of theta\n", + "line_stress_state_theta = fig_Mohr_circle.line([sigma_x0, tau_0], [sigma_y0, -tau_0],\n", + " line_dash=\"4 4\", line_color=\"red\", line_width=0.5)\n", + "points_stress_state_theta = fig_Mohr_circle.circle([sigma_x0, tau_0], [sigma_y0, -tau_0],\n", + " **mohr_points_opt, color=\"red\", fill_color=\"red\")\n", + "str_label_stress_state_theta1 = \"Rotating element \\n(\\N{GREEK SMALL LETTER SIGMA}\\N{LATIN SUBSCRIPT SMALL LETTER X}, \\N{GREEK SMALL LETTER TAU})\"\n", + "# NB: no subscript of latin y, so use gamma (very similar in the display)\n", + "str_label_stress_state_theta2 = \"Rotating element \\n(\\N{GREEK SMALL LETTER SIGMA}\\N{Greek Subscript Small Letter Gamma}, -\\N{GREEK SMALL LETTER TAU})\"\n", + "label_points_stress_state_theta = fig_Mohr_circle.text([sigma_x0, tau_0], [sigma_y0, -tau_0],\n", + " text=[str_label_stress_state_theta1, str_label_stress_state_theta2],\n", + " text_align=\"right\",\n", + " color=\"red\", x_offset=-5, y_offset=18, text_font_size=\"14px\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "update_circle_mohr = f\"\"\"\n", + "const y_var = db['y_var'][0]\n", + "const A = db['A'][0]\n", + "const b = db['b'][0]\n", + "const h = db['h'][0]\n", + "const yG = db['yG'][0]\n", + "const Iy = db['Iy'][0]\n", + "const theta_element = db['theta_element'][0]\n", + "const sigma_x0 = compute_total_sigma(compute_sigma_axial(N, A), compute_sigma_bending(y_var, M, Iy, yG))\n", + "const sigma_y0 = 0\n", + "const tau_0 = compute_total_tau(compute_tau_shear(V, compute_first_moment_of_area(y_var, b, h, yG), Iy, b))\n", + "const sigma_average = compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "const r_circle = compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// update data\n", + "db['sigma_x0'][0] = sigma_x0\n", + "db['sigma_y0'][0] = sigma_y0\n", + "db['tau_0'][0] = tau_0\n", + "db['sigma_average'][0] = sigma_average\n", + "db['r_circle_mohr'][0] = r_circle\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta'][0] = theta\n", + "\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "\"\"\"\n", + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " points_stress_state=points_stress_state,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " arrow_sigma_x1=arrows_stress_state[0], \n", + " arrow_sigma_x2=arrows_stress_state[1], \n", + " arrow_sigma_y1=arrows_stress_state[2], \n", + " arrow_sigma_y2=arrows_stress_state[3], \n", + " arrow_tau_x1=arrows_stress_state[4], \n", + " arrow_tau_x2=arrows_stress_state[5], \n", + " arrow_tau_y1=arrows_stress_state[6], \n", + " arrow_tau_y2=arrows_stress_state[7],\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "const N = compute_N(db['P'][0])\n", + "const V = compute_V(pos, q, L)\n", + "const M = compute_M(pos, q, L)\n", + "\n", + "// update data\n", + "db['N'][0] = N\n", + "db['V'][0] = V\n", + "db['M'][0] = M\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "{update_circle_mohr}\n", + "update_sigmax_state(db, arrow_sigma_x1, arrow_sigma_x2)\n", + "update_sigmay_state(db, arrow_sigma_y1, arrow_sigma_y2)\n", + "update_tau_state(db, arrow_tau_x1, arrow_tau_x2, arrow_tau_y1, arrow_tau_y2)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{models.implement_check_stateJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{mohrcircle.implement_compute_radius_mohrJS()}\n", + "{mohrcircle.implement_compute_sigma_average_mohrJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{mohrcircle.implement_update_sigmax_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmay_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_tau_stateJS(MAX_STRESS/2, SCALE_TAU)}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b = dict(source=source,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " points_stress_state=points_stress_state,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " arrow_sigma_x1=arrows_stress_state[0], \n", + " arrow_sigma_x2=arrows_stress_state[1], \n", + " arrow_sigma_y1=arrows_stress_state[2], \n", + " arrow_sigma_y2=arrows_stress_state[3], \n", + " arrow_tau_x1=arrows_stress_state[4], \n", + " arrow_tau_x2=arrows_stress_state[5], \n", + " arrow_tau_y1=arrows_stress_state[6], \n", + " arrow_tau_y2=arrows_stress_state[7],\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const yG = db['yG'][0]\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "const V = db['V'][0]\n", + "const y_var = db['y_var'][0]\n", + "const theta_element = db['theta_element'][0]\n", + "const sigma_x0 = compute_total_sigma(compute_sigma_axial(N, A), compute_sigma_bending(y_var, M, Iy, yG))\n", + "const sigma_y0 = 0\n", + "const tau_0 = compute_total_tau(compute_tau_shear(V, compute_first_moment_of_area(y_var, b, h, yG), Iy, b))\n", + "const sigma_average = compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "const r_circle = compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "db['sigma_x0'][0] = sigma_x0\n", + "db['sigma_y0'][0] = sigma_y0\n", + "db['tau_0'][0] = tau_0\n", + "db['sigma_average'][0] = sigma_average\n", + "db['r_circle_mohr'][0] = r_circle\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta'][0] = theta\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "// Mohr circle\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "// stress state\n", + "update_sigmax_state(db, arrow_sigma_x1, arrow_sigma_x2)\n", + "update_sigmay_state(db, arrow_sigma_y1, arrow_sigma_y2)\n", + "update_tau_state(db, arrow_tau_x1, arrow_tau_x2, arrow_tau_y1, arrow_tau_y2)\n", + "// stress state (theta)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{mohrcircle.implement_compute_radius_mohrJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_sigma_average_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{mohrcircle.implement_update_sigmax_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmay_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_tau_stateJS(MAX_STRESS/2, SCALE_TAU)}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b, code=code_change_b)\n", + "\n", + "\n", + "args_slider_h = dict(source=source,\n", + " s_ss=source_section_scheme,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " slider_y=slider_y,\n", + " beam=beam,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " points_stress_state=points_stress_state,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " arrow_sigma_x1=arrows_stress_state[0], \n", + " arrow_sigma_x2=arrows_stress_state[1], \n", + " arrow_sigma_y1=arrows_stress_state[2], \n", + " arrow_sigma_y2=arrows_stress_state[3], \n", + " arrow_tau_x1=arrows_stress_state[4], \n", + " arrow_tau_x2=arrows_stress_state[5], \n", + " arrow_tau_y1=arrows_stress_state[6], \n", + " arrow_tau_y2=arrows_stress_state[7],\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_change_h = f\"\"\"\n", + "// solve sliders conflict\n", + "const db = source.data\n", + "const h = cb_obj.value // value of the slider\n", + "if (h < db['y_var'][0]) {{\n", + " db['y_var'][0] = h\n", + "}}\n", + "slider_y.end = h\n", + "if (h < slider_y.value) {{\n", + " slider_y.value = h\n", + "}}\n", + "\n", + "// retrieve data used\n", + "const data_ss = s_ss.data\n", + "const b = db['b'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const N = db['N'][0]\n", + "const V = db['V'][0]\n", + "const M = db['M'][0]\n", + "const yG = compute_centroid_y(h)\n", + "const y_var = db['y_var'][0]\n", + "const theta_element = db['theta_element'][0]\n", + "const sigma_x0 = compute_total_sigma(compute_sigma_axial(N, A), compute_sigma_bending(y_var, M, Iy, yG))\n", + "const sigma_y0 = 0\n", + "const tau_0 = compute_total_tau(compute_tau_shear(V, compute_first_moment_of_area(y_var, b, h, yG), Iy, b))\n", + "const sigma_average = compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "const r_circle = compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['yG'][0] = yG\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "beam.glyph.height = h // change the beam height\n", + "beam.glyph.y = h/2\n", + "data_ss['y'][1] = h // change the height of the section in the diagrams\n", + "db['sigma_x0'][0] = sigma_x0\n", + "db['sigma_y0'][0] = sigma_y0\n", + "db['tau_0'][0] = tau_0\n", + "db['sigma_average'][0] = sigma_average\n", + "db['r_circle_mohr'][0] = r_circle\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta'][0] = theta\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "// Mohr circle\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "// stress state\n", + "update_sigmax_state(db, arrow_sigma_x1, arrow_sigma_x2)\n", + "update_sigmay_state(db, arrow_sigma_y1, arrow_sigma_y2)\n", + "update_tau_state(db, arrow_tau_x1, arrow_tau_x2, arrow_tau_y1, arrow_tau_y2)\n", + "// stress state (theta)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_ss.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{mohrcircle.implement_compute_radius_mohrJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_sigma_average_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{mohrcircle.implement_update_sigmax_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmay_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_tau_stateJS(MAX_STRESS/2, SCALE_TAU)}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head,\n", + " N_diag=N_diag,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " points_stress_state=points_stress_state,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " arrow_sigma_x1=arrows_stress_state[0],\n", + " arrow_sigma_x2=arrows_stress_state[1],\n", + " arrow_sigma_y1=arrows_stress_state[2],\n", + " arrow_sigma_y2=arrows_stress_state[3],\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const P = {P}*(1-f)\n", + "const db = source.data\n", + "const N = compute_N(P)\n", + "const M = db['M'][0]\n", + "const A = db['A'][0]\n", + "const Iy = db['Iy'][0]\n", + "const yG = db['yG'][0]\n", + "const y_var = db['y_var'][0]\n", + "const theta_element = db['theta_element'][0]\n", + "const sigma_x0 = compute_total_sigma(compute_sigma_axial(N, A), compute_sigma_bending(y_var, M, Iy, yG))\n", + "const sigma_y0 = 0\n", + "const tau_0 = db['tau_0'][0]\n", + "const sigma_average = compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "const r_circle = compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// apply the changes\n", + "db['P'][0] = P\n", + "db['N'][0] = N\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "db['sigma_x0'][0] = sigma_x0\n", + "db['sigma_y0'][0] = sigma_y0\n", + "db['sigma_average'][0] = sigma_average\n", + "db['r_circle_mohr'][0] = r_circle\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta'][0] = theta\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_N_diagram(db, N_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "// Mohr circle\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "// stress state\n", + "update_sigmax_state(db, arrow_sigma_x1, arrow_sigma_x2)\n", + "update_sigmay_state(db, arrow_sigma_y1, arrow_sigma_y2)\n", + "// stress state (theta)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_N_diagramJS(discr_NVM)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{mohrcircle.implement_compute_radius_mohrJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_sigma_average_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{mohrcircle.implement_update_sigmax_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmay_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " V_diag=V_diag,\n", + " M_diag=M_diag,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " points_stress_state=points_stress_state,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " arrow_sigma_x1=arrows_stress_state[0], \n", + " arrow_sigma_x2=arrows_stress_state[1], \n", + " arrow_sigma_y1=arrows_stress_state[2], \n", + " arrow_sigma_y2=arrows_stress_state[3], \n", + " arrow_tau_x1=arrows_stress_state[4], \n", + " arrow_tau_x2=arrows_stress_state[5], \n", + " arrow_tau_y1=arrows_stress_state[6], \n", + " arrow_tau_y2=arrows_stress_state[7],\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "const N = db['N'][0]\n", + "const V = compute_V(pos, q, L)\n", + "const M = compute_M(pos, q, L)\n", + "const y_var = db['y_var'][0]\n", + "const A = db['A'][0]\n", + "const b = db['b'][0]\n", + "const h = db['h'][0]\n", + "const yG = db['yG'][0]\n", + "const Iy = db['Iy'][0]\n", + "const theta_element = db['theta_element'][0]\n", + "const sigma_x0 = compute_total_sigma(compute_sigma_axial(N, A), compute_sigma_bending(y_var, M, Iy, yG))\n", + "const sigma_y0 = 0\n", + "const tau_0 = compute_total_tau(compute_tau_shear(V, compute_first_moment_of_area(y_var, b, h, yG), Iy, b))\n", + "const sigma_average = compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "const r_circle = compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// update data\n", + "db['q'][0] = q\n", + "db['V'][0] = V\n", + "db['M'][0] = M\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "db['sigma_x0'][0] = sigma_x0\n", + "db['sigma_y0'][0] = sigma_y0\n", + "db['tau_0'][0] = tau_0\n", + "db['sigma_average'][0] = sigma_average\n", + "db['r_circle_mohr'][0] = r_circle\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta'][0] = theta\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_V_diagram(db, V_diag)\n", + "update_M_diagram(db, M_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "// Mohr circle\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "// stress state\n", + "update_sigmax_state(db, arrow_sigma_x1, arrow_sigma_x2)\n", + "update_sigmay_state(db, arrow_sigma_y1, arrow_sigma_y2)\n", + "update_tau_state(db, arrow_tau_x1, arrow_tau_x2, arrow_tau_y1, arrow_tau_y2)\n", + "// stress state (theta)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_update_V_diagramJS(discr_NVM)}\n", + "{sb.implement_update_M_diagramJS(discr_NVM)}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{mohrcircle.implement_compute_radius_mohrJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_sigma_average_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{mohrcircle.implement_update_sigmax_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmay_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_tau_stateJS(MAX_STRESS/2, SCALE_TAU)}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "\n", + "args_slider_theta = dict(source=source,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " points_stress_state=points_stress_state,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " stress_state_theta=stress_state_theta,\n", + " label_stress_state_theta=label_stress_state_theta,\n", + " arc_theta_element=arc_theta_element,\n", + " label_theta_element= label_theta_element,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " rotating_axis=rotating_axis,\n", + " beam_position=beam_position,\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_slider_theta = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const theta_element = cb_obj.value/180*Math.PI\n", + "const sigma_x0 = db['sigma_x0'][0]\n", + "const sigma_y0 = db['sigma_y0'][0]\n", + "const tau_0 = db['tau_0'][0]\n", + "const sigma_average = db['sigma_average'][0]\n", + "const r_circle = db['r_circle_mohr'][0]\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// update data\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta_element'][0] = theta_element\n", + "db['theta'][0] = theta\n", + "\n", + "// update\n", + "// square point:\n", + "beam_position.glyph.angle = theta_element\n", + "// stress state element\n", + "update_stress_state_elements(db, stress_state_theta, rotating_axis, label_stress_state_theta, arc_theta_element, label_theta_element)\n", + "// stress state (theta)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "// update Mohr circle\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{mohrcircle.implement_update_stress_state_elementsJS(MAX_STRESS, MAX_DIM_STRESS_STATE)}\n", + "{js.implement_arrow_growthJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "update_slider_theta = CustomJS(args=args_slider_theta, code=code_slider_theta)\n", + "\n", + "\n", + "args_slider_y = dict(source=source,\n", + " Mohr_circle=Mohr_circle,\n", + " line_stress_state=line_stress_state,\n", + " points_stress_state=points_stress_state,\n", + " line_stress_state_theta=line_stress_state_theta,\n", + " points_stress_state_theta=points_stress_state_theta,\n", + " label_points_stress_state=label_points_stress_state,\n", + " label_points_stress_state_theta=label_points_stress_state_theta,\n", + " arc_theta_Mohr=arc_theta_Mohr,\n", + " label_theta_Mohr=label_theta_Mohr,\n", + " arc_theta_p_Mohr=arc_theta_p_Mohr,\n", + " label_theta_p_Mohr=label_theta_p_Mohr,\n", + " beam_position=beam_position,\n", + " arrow_sigma_x1=arrows_stress_state[0], \n", + " arrow_sigma_x2=arrows_stress_state[1], \n", + " arrow_sigma_y1=arrows_stress_state[2], \n", + " arrow_sigma_y2=arrows_stress_state[3], \n", + " arrow_tau_x1=arrows_stress_state[4], \n", + " arrow_tau_x2=arrows_stress_state[5], \n", + " arrow_tau_y1=arrows_stress_state[6], \n", + " arrow_tau_y2=arrows_stress_state[7],\n", + " arrow_sigma_x1_theta=arrows_stress_state_theta[0], \n", + " arrow_sigma_x2_theta=arrows_stress_state_theta[1], \n", + " arrow_sigma_y1_theta=arrows_stress_state_theta[2], \n", + " arrow_sigma_y2_theta=arrows_stress_state_theta[3], \n", + " arrow_tau_x1_theta=arrows_stress_state_theta[4], \n", + " arrow_tau_x2_theta=arrows_stress_state_theta[5], \n", + " arrow_tau_y1_theta=arrows_stress_state_theta[6], \n", + " arrow_tau_y2_theta=arrows_stress_state_theta[7])\n", + "code_slider_y = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const y_var = cb_obj.value\n", + "const N = db['N'][0]\n", + "const V = db['V'][0]\n", + "const M = db['M'][0]\n", + "const A = db['A'][0]\n", + "const b = db['b'][0]\n", + "const h = db['h'][0]\n", + "const yG = db['yG'][0]\n", + "const Iy = db['Iy'][0]\n", + "const theta_element = db['theta_element'][0]\n", + "const sigma_x0 = compute_total_sigma(compute_sigma_axial(N, A), compute_sigma_bending(y_var, M, Iy, yG))\n", + "const sigma_y0 = 0\n", + "const tau_0 = compute_total_tau(compute_tau_shear(V, compute_first_moment_of_area(y_var, b, h, yG), Iy, b))\n", + "const sigma_average = compute_sigma_average_mohr(sigma_x0, sigma_y0)\n", + "const r_circle = compute_radius_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta_principal = compute_principal_theta_mohr(sigma_x0, sigma_y0, tau_0)\n", + "const theta = compute_theta_mohr(theta_element, theta_principal)\n", + "const new_state = compute_stress_state_mohr(sigma_average, r_circle, theta)\n", + "\n", + "// update data\n", + "db['y_var'][0] = y_var\n", + "db['sigma_x0'][0] = sigma_x0\n", + "db['sigma_y0'][0] = sigma_y0\n", + "db['tau_0'][0] = tau_0\n", + "db['sigma_average'][0] = sigma_average\n", + "db['r_circle_mohr'][0] = r_circle\n", + "db['sigma_x'][0] = new_state[0]\n", + "db['sigma_y'][0] = new_state[1]\n", + "db['tau'][0] = new_state[2]\n", + "db['theta'][0] = theta\n", + "\n", + "// update\n", + "// square point:\n", + "beam_position.glyph.y = y_var\n", + "// update Mohr circle\n", + "update_circle_mohr(db, Mohr_circle, line_stress_state, points_stress_state, label_points_stress_state, line_stress_state_theta, points_stress_state_theta, label_points_stress_state_theta, arc_theta_Mohr, label_theta_Mohr, arc_theta_p_Mohr, label_theta_p_Mohr)\n", + "// stress state\n", + "update_sigmax_state(db, arrow_sigma_x1, arrow_sigma_x2)\n", + "update_sigmay_state(db, arrow_sigma_y1, arrow_sigma_y2)\n", + "update_tau_state(db, arrow_tau_x1, arrow_tau_x2, arrow_tau_y1, arrow_tau_y2)\n", + "// stress state (theta)\n", + "update_sigmax_state_theta(db, arrow_sigma_x1_theta, arrow_sigma_x2_theta)\n", + "update_sigmay_state_theta(db, arrow_sigma_y1_theta, arrow_sigma_y2_theta)\n", + "update_tau_state_theta(db, arrow_tau_x1_theta,arrow_tau_x2_theta, arrow_tau_y1_theta, arrow_tau_y2_theta)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{mohrcircle.implement_compute_radius_mohrJS()}\n", + "{mohrcircle.implement_compute_stress_state_mohrJS()}\n", + "{mohrcircle.implement_compute_sigma_average_mohrJS()}\n", + "{mohrcircle.implement_compute_principal_theta_mohrJS()}\n", + "{mohrcircle.implement_compute_theta_mohrJS()}\n", + "{mohrcircle.implement_update_circle_mohrJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{mohrcircle.implement_update_sigmax_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_sigmay_stateJS(MAX_STRESS/2)}\n", + "{mohrcircle.implement_update_tau_stateJS(MAX_STRESS/2, SCALE_TAU)}\n", + "{mohrcircle.implement_update_sigmax_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_sigmay_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2)}\n", + "{mohrcircle.implement_update_tau_state_thetaJS(MAX_STRESS/2, MAX_STRESS*2, SCALE_TAU)}\n", + "\"\"\"\n", + "update_slider_y = CustomJS(args=args_slider_y, code=code_slider_y)\n", + "\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)\n", + "slider_theta_element.js_on_change('value', update_slider_theta)\n", + "slider_y.js_on_change('value', update_slider_y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme.\n", + "Note that the size of the tau arrows in the stress state elements is 5 times bigger (check the value of the constant SCALE_TAU to change it)." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_scheme,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout),\n", + " slider_b,\n", + " slider_h,\n", + " # row(div_geo, div_forces),\n", + " slider_y,\n", + " slider_theta_element,\n", + " Spacer(height=padding_layout),\n", + " slider_position,\n", + " slider_q,\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P))),\n", + " column(fig_beam,\n", + " Spacer(height=padding_layout),\n", + " fig_N,\n", + " fig_V,\n", + " fig_M)),\n", + " row(column(\n", + " row(fig_NM_section, fig_axial_strain, fig_stress_N, fig_bending_strain, fig_stress_M, fig_stress_sigma),\n", + " row(fig_V_section, Spacer(width=FIG_B_ss), fig_stress_V, Spacer(width=FIG_B_ss), Spacer(width=FIG_B_ss), fig_stress_tau),\n", + " ))\n", + " ),\n", + " column(fig_Mohr_circle, fig_stress_state)\n", + " ],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_plastic.ipynb b/Simple Beam DEMOs/sb_plastic.ipynb new file mode 100644 index 0000000..f43e5d2 --- /dev/null +++ b/Simple Beam DEMOs/sb_plastic.ipynb @@ -0,0 +1,1341 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Plastic Analysis\n", + "In this first notebook, the plastic analysis is presented." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer, Text\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import stress_strain_elastic as ststel\n", + "from cienpy import stress_strain_plastic as ststpl\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "# h = 220.6265 # [mm]\n", + "b = 100 # [mm]\n", + "q = 4; # [kN/m]\n", + "P = 10; # [kN]\n", + "# P = 587.418; # [kN]\n", + "\n", + "# Choose the material parameters\n", + "E_steel = 200e3 # [MPa] steel\n", + "fy_steel = 355 # [MPa] steel\n", + "E = E_steel\n", + "fy = fy_steel\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "yG = beam_section.compute_centroid_y(h)\n", + "y_n_axis = ststel.compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_Q = q/4*5\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "data_section_scheme = dict(\n", + " x=[0, 0], \n", + " y=[0, h]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " E=[E],\n", + " fy=[fy],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " yG=[yG],\n", + " y_n_axis=[y_n_axis],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " q=[q],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source_section_scheme = ColumnDataSource(data_section_scheme)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 3 - Diagrams):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "DIV_B_GEO = 170\n", + "DIV_B_FORCES = 170\n", + "\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B*0.8, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(width= DIV_B_GEO, \n", + " text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# uniform load (beam)\n", + "u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE], width=L, height=q/SCALE,\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + "label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "beam_position = fig_beam.circle('x', 'y', **pos_opt)\n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(width=DIV_B_FORCES, \n", + " text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))\n", + "\n", + "\n", + "# figures for the diagrams\n", + "options_diag = dict(\n", + " toolbar_location=None,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_width=FIG_B_B,\n", + " x_range=fig_beam.x_range\n", + ")\n", + "fig_N = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Axial force\", \"@y kN\")],\n", + " y_axis_label=\"Axial force N [kN]\",\n", + " plot_height=int(FIG_H_B*0.8),\n", + " title=\"N V M Diagrams\")\n", + "fig_V = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Shear force\", \"@y kN\")],\n", + " y_axis_label=\"Shear force V [kN]\",\n", + " plot_height=int(FIG_H_B*0.8))\n", + "fig_M = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Bending moment\", \"@y kNm\")],\n", + " y_axis_label=\"Bending moment M [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "fig_N.xaxis.visible = False\n", + "fig_V.xaxis.visible = False\n", + "\n", + "\n", + "# plot N V M\n", + "N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)\n", + "V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)\n", + "M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)\n", + "\n", + "# point that shows the position that it's analyzed\n", + "N_position = fig_N.circle('x', 'N', **pos_opt)\n", + "V_position = fig_V.circle('x', 'V', **pos_opt)\n", + "M_position = fig_M.circle('x', 'M', **pos_opt)\n", + "\n", + "\n", + "# figures for the stresses and strains\n", + "FIG_B_ss = 200\n", + "FIG_H_ss = 200\n", + "options_stress_strain = dict(\n", + " toolbar_location=None,\n", + " y_axis_label=\"Height h [mm]\",\n", + " plot_height=FIG_H_ss\n", + ")\n", + "fig_stress_N = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2099 [MPa]\")\n", + "fig_stress_N.yaxis.visible = False\n", + "fig_axial_strain = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2099 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_axial_strain.yaxis.visible = False\n", + "fig_stress_M = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending stress and centroid\",\n", + " y_range=fig_stress_N.y_range,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2098 [MPa]\")\n", + "fig_stress_M.yaxis.visible = False\n", + "fig_bending_strain = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2098 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_bending_strain.yaxis.visible = False\n", + "fig_stress_V = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Shear stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU}\\u1d65 [MPa]\")\n", + "fig_stress_V.yaxis.visible = False\n", + "fig_stress_sigma = figure(**options_stress_strain,\n", + " plot_width=int(FIG_B_ss*1.2),\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress (green=yield) and N.A.\",\n", + " y_range=fig_stress_N.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA} [MPa]\")\n", + "fig_stress_tau = figure(**options_stress_strain,\n", + " plot_width=int(FIG_B_ss*1.2),\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER TAU}\",\n", + " y_range=fig_stress_V.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU} [MPa]\")\n", + "\n", + "# plot stress N V M\n", + "discr_stress_strain = 10\n", + "scale_x = 25\n", + "y_discr = np.linspace(0, h, discr_stress_strain)\n", + "sigma_N = ststel.compute_sigma_axial(y_discr, 0, A)\n", + "N_stress_diag = models.stress_diagram(fig_stress_N, sigma_N, h,\n", + " source_section_scheme, scale_x=scale_x/10)\n", + "sigma_M = ststel.compute_sigma_bending(y_discr, 0, Iy, yG)\n", + "(M_stress_diag, centroid) = models.stress_diagram(fig_stress_M, sigma_M, h,\n", + " source_section_scheme, True, yG, scale_x=scale_x)\n", + "S_rect = beam_section.compute_first_moment_of_area(y_discr, b, h, yG)\n", + "tau_V = ststel.compute_tau_shear(y_discr, 0, S_rect, Iy, b)\n", + "V_stress_diag = models.stress_diagram(fig_stress_V, tau_V, h, source_section_scheme, scale_x=1)\n", + "\n", + "# plot stress sigma (moved below) and tau\n", + "tau_total = tau_V\n", + "tau_stress_diag = models.stress_diagram(fig_stress_tau, tau_total, h,\n", + " source_section_scheme, scale_x=1)\n", + "\n", + "# plot strain N M\n", + "strain_axial = ststel.compute_epsilon_axial(y_discr, sigma_N, E)\n", + "axial_strain_diag = models.strain_diagram(fig_axial_strain, strain_axial, h, source_section_scheme)\n", + "strain_bending = ststel.compute_epsilon_bending(y_discr, sigma_M, E)\n", + "bending_strain_diag = models.strain_diagram(fig_bending_strain, strain_bending, h, source_section_scheme)\n", + "\n", + "\n", + "# figures for NVM\n", + "fig_NM_section = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " title=\"N and M at position x\",\n", + " match_aspect=True)\n", + "fig_NM_section.axis.visible = False\n", + "fig_NM_section.grid.grid_line_alpha = 0\n", + "\n", + "fig_V_section = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " title=\"V at position x\",\n", + " match_aspect=True)\n", + "fig_V_section.axis.visible = False\n", + "fig_V_section.grid.grid_line_alpha = 0\n", + "\n", + "# section with NVM\n", + "models.section_diagram(fig_NM_section)\n", + "models.section_diagram(fig_V_section)\n", + "\n", + "# NVM in section\n", + "section_N = models.force_vector(fig_NM_section, 0, 0, 0, 0, 0, 'red')\n", + "section_V = models.force_vector(fig_V_section, 0, 0, 0, 0, 0, 'red')\n", + "(section_M_line, section_M_head, source_section_M) = models.define_curvedArrow(fig_NM_section, 0, 0, 0, size_head=0)\n", + "\n", + "# NVM label in section\n", + "OFFSET_N = 1\n", + "label_N_section = fig_NM_section.text(x=[P*1.1], y=[OFFSET_N], text=[\"\"], text_color=\"red\", text_baseline='bottom')\n", + "label_M_section = fig_NM_section.text(x=[OFFSET_N*6], y=[-OFFSET_N*5], text=[\"\"], text_color=\"red\", text_baseline='top')\n", + "label_V_section = fig_V_section.text(x=[OFFSET_N*5], y=[0], text=[\"\"], text_color=\"red\", text_baseline='middle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# choose different elastic modulus\n", + "E_wood = 8e3 # [MPa]\n", + "E_concrete = 26e3 # [MPa]\n", + "E_ceramic = 300e3 # [MPa]\n", + "slider_elastic = Slider(\n", + " title=\"Change the elastic modulus [MPa]\",\n", + " start=E_wood,\n", + " end=E_ceramic,\n", + " step=1e3,\n", + " value=E,\n", + " margin=(5, 5, 0, 5)\n", + ")\n", + "\n", + "\n", + "# show values of E\n", + "div_E = Div(margin=(0, 5, 0, 5),\n", + " text=f\"\"\"\n", + "

\n", + " Ewood = {math.trunc(E_wood/1e3)} GPa; Econcrete = {math.trunc(E_concrete/1e3)} GPa
\n", + " Esteel = {math.trunc(E_steel/1e3)} GPa; Eceramic = {math.trunc(E_ceramic/1e3)} GPa

\n", + " \"\"\")\n", + "\n", + "\n", + "# choose different yield strength\n", + "fy_wood = 16 # [MPa] (bending)\n", + "fy_concrete = 25 # [MPa]\n", + "fy_glass = 1000 # [MPa] (compressive)\n", + "slider_yield = Slider(\n", + " title=\"Change the yield strength [MPa]\",\n", + " start=fy_wood,\n", + " end=fy_glass,\n", + " step=1,\n", + " value=fy,\n", + " margin=(0, 5, 0, 5)\n", + ")\n", + "\n", + "\n", + "# show values of fy\n", + "div_fy = Div(margin=(0, 5, 0, 5),\n", + " text=f\"\"\"\n", + "

\n", + " fy,wood = {math.trunc(fy_wood)} MPa; fy,concrete = {math.trunc(fy_concrete)} MPa
\n", + " fy,steel = {math.trunc(fy_steel)} MPa; fy,glass = {math.trunc(fy_glass)} MPa

\n", + " \"\"\")\n", + "\n", + "\n", + "# add total strain epsilon\n", + "fig_total_strain = figure(**options_stress_strain,\n", + " plot_width=FIG_B_ss,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total strain (green=yield)\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON} [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_total_strain.yaxis.visible = False\n", + "\n", + "\n", + "# add the strain and stress with yield implemented\n", + "# plastic\n", + "discr_pl = 2000\n", + "(stress_pl, strain_pl, y_discr_pl, yNA_pl) = ststpl.compute_total_stress_strain(discr_pl, h, fy, E, N, M, A, Iy, yG)\n", + "tmp_y = np.linspace(0, h, len(stress_pl))\n", + "total_stress_pl_diag = fig_stress_sigma.line([0, *stress_pl, 0], [0, *tmp_y, h], color='green')\n", + "total_strain_pl_diag = fig_total_strain.line(strain_pl*0, y_discr_pl, color='green')\n", + "# elastic\n", + "total_strain = ststel.compute_total_epsilon(strain_axial, strain_bending)\n", + "total_strain_diag = models.strain_diagram(fig_total_strain, total_strain, h, source_section_scheme)\n", + "# (moved from above, total stress sigma elastic)\n", + "sigma_total = sigma_M + sigma_N\n", + "(sigma_stress_diag, neutral_axis) = models.stress_diagram(fig_stress_sigma, sigma_total, h,\n", + " source_section_scheme,True, yG, scale_x=scale_x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " discr_stress=discr_stress_strain,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update data\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{models.implement_check_stateJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{ststel.implement_compute_tau_shearJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "{ststel.implement_compute_total_sigmaJS()}\n", + "{ststel.implement_compute_total_tauJS()}\n", + "{ststel.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b = dict(source=source,\n", + " s_b=source_beam,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const yG = db['yG'][0]\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{ststel.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{ststel.implement_compute_total_sigmaJS()}\n", + "{ststel.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{ststel.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{ststel.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b, code=code_change_b)\n", + "\n", + "\n", + "args_slider_h = dict(source=source,\n", + " s_b=source_beam,\n", + " s_ss=source_section_scheme,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const data_ss = s_ss.data\n", + "const b = db['b'][0]\n", + "const h = cb_obj.value // value of the slider\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "const yG = compute_centroid_y(h)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['yG'][0] = yG\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "data_ss['y'][1] = h // change the height of the section in the diagrams\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_ss.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{ststel.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{ststel.implement_compute_total_sigmaJS()}\n", + "{ststel.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{ststel.implement_compute_tau_shearJS()}\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head,\n", + " N_diag=N_diag,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "\n", + "// apply the changes\n", + "db['P'][0] = {P}*(1-f)\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_N_diagram(db, N_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_N_diagramJS(discr_NVM)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{ststel.implement_compute_neutral_axisJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{ststel.implement_compute_total_sigmaJS()}\n", + "{ststel.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{ststel.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " V_diag=V_diag,\n", + " M_diag=M_diag,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['q'][0] = q\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_V_diagram(db, V_diag)\n", + "update_M_diagram(db, M_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_update_V_diagramJS(discr_NVM)}\n", + "{sb.implement_update_M_diagramJS(discr_NVM)}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{ststel.implement_compute_neutral_axisJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{ststel.implement_compute_total_sigmaJS()}\n", + "{ststel.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{ststel.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "\n", + "args_slider_yield = dict(source=source,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_slider_yield = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const fy = cb_obj.value\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['fy'][0] = fy\n", + "\n", + "// update\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "{js.implement_linspaceJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "\"\"\"\n", + "update_slider_yield = CustomJS(args=args_slider_yield, code=code_slider_yield)\n", + "\n", + "# for the implementation in the other nbs!!!\n", + "# args_slider_elastic = dict(source=source,\n", + "# N_stress_diag=N_stress_diag,\n", + "# axial_strain_diag=axial_strain_diag,\n", + "# M_stress_diag=M_stress_diag,\n", + "# bending_strain_diag=bending_strain_diag,\n", + "# centroid=centroid)\n", + "# code_slider_elastic = f\"\"\"\n", + "# // retrieve data\n", + "# const db = source.data\n", + "# const E = cb_obj.value\n", + "\n", + "# // update E\n", + "# db['E'][0] = E\n", + "\n", + "# // update\n", + "# update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "# update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "\n", + "# // apply changes\n", + "# source.change.emit()\n", + "\n", + "# // declare functions\n", + "# {js.implement_linspaceJS()}\n", + "# {sb.implement_compute_NJS()}\n", + "# {js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "# {js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "# {ststel.implement_compute_epsilon_bendingJS()}\n", + "# {ststel.implement_compute_epsilon_axialJS()}\n", + "# {ststel.implement_compute_sigma_axialJS()}\n", + "# {js.implement_update_stress_diagramJS()}\n", + "# {js.implement_update_strain_diagramJS()}\n", + "# {ststel.implement_compute_sigma_bendingJS()}\n", + "# \"\"\"\n", + "# update_slider_elastic = CustomJS(args=args_slider_elastic, code=code_slider_elastic)\n", + "\n", + "# slider_elastic.js_on_change('value', update_slider_elastic)\n", + "\n", + "args_slider_elastic = dict(source=source,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " centroid=centroid,\n", + " total_strain_diag=total_strain_diag,\n", + " total_stress_pl_diag=total_stress_pl_diag,\n", + " total_strain_pl_diag=total_strain_pl_diag)\n", + "code_slider_elastic = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const E = cb_obj.value\n", + "\n", + "// update E\n", + "db['E'][0] = E\n", + "\n", + "// update\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_plastic_stress_strain(db, total_strain_diag, total_strain_pl_diag, total_stress_pl_diag)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_linspaceJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{ststel.implement_compute_epsilon_bendingJS()}\n", + "{ststel.implement_compute_epsilon_axialJS()}\n", + "{ststel.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{ststel.implement_compute_sigma_bendingJS()}\n", + "{js.implement_update_plastic_stress_strainJS(discr_pl)}\n", + "{ststpl.implement_compute_NyJS()}\n", + "{ststpl.implement_compute_MyJS()}\n", + "{ststpl.implement_compute_total_stress_strainJS()}\n", + "{ststpl.implement_support_function_plasticJS()}\n", + "{ststel.implement_compute_total_epsilonJS()}\n", + "\"\"\"\n", + "update_slider_elastic = CustomJS(args=args_slider_elastic, code=code_slider_elastic)\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)\n", + "slider_elastic.js_on_change('value', update_slider_elastic)\n", + "slider_yield.js_on_change('value', update_slider_yield)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_scheme,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout*3),\n", + " slider_b,\n", + " slider_h,\n", + " # row(div_geo, div_forces),\n", + " slider_position,\n", + " slider_q,\n", + " slider_elastic,\n", + " div_E,\n", + " slider_yield,\n", + " div_fy,\n", + " # Spacer(height=padding_layout),\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P))),\n", + " column(fig_beam,\n", + " Spacer(height=padding_layout),\n", + " fig_N,\n", + " fig_V,\n", + " fig_M)),\n", + " row(column(\n", + " row(fig_NM_section, fig_axial_strain, fig_stress_N, fig_bending_strain, fig_stress_M, fig_total_strain, fig_stress_sigma),\n", + " row(fig_V_section, Spacer(width=FIG_B_ss), fig_stress_V, Spacer(width=FIG_B_ss), Spacer(width=FIG_B_ss), Spacer(width=FIG_B_ss), fig_stress_tau),\n", + " ))\n", + " ),\n", + " ],\n", + "])\n", + "\n", + "show(layout1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "TODO:\n", + "- add slider E in some NB\n", + "- bigger N and M for plastic\n", + "- change EVERYWHERE neutral_axis with horizontal infinite line?" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_stress.ipynb b/Simple Beam DEMOs/sb_stress.ipynb new file mode 100644 index 0000000..c3cfe92 --- /dev/null +++ b/Simple Beam DEMOs/sb_stress.ipynb @@ -0,0 +1,1072 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Stress and Strain\n", + "In this first notebook, the stresses and strains inside the element are presented." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer, Text\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import rectangular_section as beam_section\n", + "from cienpy import stress_strain_elastic as stst\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry and uniform load. Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "q = 4; # [kN/m]\n", + "P = 10; # [kN]\n", + "\n", + "# Choose the material parameters\n", + "E = 200e3 # [MPa]\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h) # [mm4] weak axis\n", + "yG = beam_section.compute_centroid_y(h)\n", + "y_n_axis = stst.compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_Q = q/4*5\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "data_section_scheme = dict(\n", + " x=[0, 0], \n", + " y=[0, h]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " E=[E],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " yG=[yG],\n", + " y_n_axis=[y_n_axis],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " q=[q],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source_section_scheme = ColumnDataSource(data_section_scheme)\n", + "source = ColumnDataSource(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 3 - Diagrams):" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "DIV_B_GEO = 170\n", + "DIV_B_FORCES = 170\n", + "\n", + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B*0.8, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "\n", + "# Cat with salad for scale (if not visualized, remove this part because the browser don't support it correctly)\n", + "h_img = 150 # mm\n", + "fig_section.image_url(url=['https://stickerly.pstatic.net/sticker_pack/QFZXZVMOmb6NeoBCIzEqNw/01OWRN/4/ac6af3b7-d096-4359-b0df-480fd612b28a.png'], x=-h_img/2, y=-MAX_H/2*1.01, h=h_img, w=h_img)\n", + "fig_section.text(x=[0], y=[-MAX_H/2-h_img*1.2], text_align=\"center\", text=[f\"Cat with salad for scale (h={h_img} mm)\"], text_font_size=\"10px\")\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(width= DIV_B_GEO, \n", + " text=beam_section.div_text_geo(round(h), round(b), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=20,\n", + " end=MAX_H,\n", + " step=20,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# uniform load (beam)\n", + "u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE], width=L, height=q/SCALE,\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + "label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "beam_position = fig_beam.circle('x', 'y', **pos_opt)\n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(width=DIV_B_FORCES, \n", + " text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))\n", + "\n", + "\n", + "# figures for the diagrams\n", + "options_diag = dict(\n", + " toolbar_location=None,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_width=FIG_B_B,\n", + " x_range=fig_beam.x_range\n", + ")\n", + "fig_N = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Axial force\", \"@y kN\")],\n", + " y_axis_label=\"Axial force N [kN]\",\n", + " plot_height=int(FIG_H_B*0.8),\n", + " title=\"N V M Diagrams\")\n", + "fig_V = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Shear force\", \"@y kN\")],\n", + " y_axis_label=\"Shear force V [kN]\",\n", + " plot_height=int(FIG_H_B*0.8))\n", + "fig_M = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Bending moment\", \"@y kNm\")],\n", + " y_axis_label=\"Bending moment M [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "fig_N.xaxis.visible = False\n", + "fig_V.xaxis.visible = False\n", + "\n", + "\n", + "# plot N V M\n", + "N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)\n", + "V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)\n", + "M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)\n", + "\n", + "# point that shows the position that it's analyzed\n", + "N_position = fig_N.circle('x', 'N', **pos_opt)\n", + "V_position = fig_V.circle('x', 'V', **pos_opt)\n", + "M_position = fig_M.circle('x', 'M', **pos_opt)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# figures for the stresses and strains\n", + "FIG_B_ss = 200\n", + "FIG_H_ss = 200\n", + "options_stress_strain = dict(\n", + " toolbar_location=None,\n", + " y_axis_label=\"Height h [mm]\",\n", + " plot_width=FIG_B_ss,\n", + " plot_height=FIG_H_ss\n", + ")\n", + "fig_stress_N = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2099 [MPa]\")\n", + "fig_stress_N.yaxis.visible = False\n", + "fig_axial_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2099 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_axial_strain.yaxis.visible = False\n", + "fig_stress_M = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending stress and centroid\",\n", + " y_range=fig_stress_N.y_range,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2098 [MPa]\")\n", + "fig_stress_M.yaxis.visible = False\n", + "fig_bending_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2098 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_bending_strain.yaxis.visible = False\n", + "fig_stress_V = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Shear stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU}\\u1d65 [MPa]\")\n", + "fig_stress_V.yaxis.visible = False\n", + "fig_stress_sigma = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER SIGMA} and neutral axis\",\n", + " y_range=fig_stress_N.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA} [MPa]\")\n", + "fig_stress_tau = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER TAU}\",\n", + " y_range=fig_stress_V.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU} [MPa]\")\n", + "\n", + "# plot stress N V M\n", + "discr_stress_strain = 10\n", + "scale_x = 25\n", + "y_discr = np.linspace(0, h, discr_stress_strain)\n", + "sigma_N = stst.compute_sigma_axial(y_discr, 0, A)\n", + "N_stress_diag = models.stress_diagram(fig_stress_N, sigma_N, h,\n", + " source_section_scheme, scale_x=scale_x/10)\n", + "sigma_M = stst.compute_sigma_bending(y_discr, 0, Iy, yG)\n", + "(M_stress_diag, centroid) = models.stress_diagram(fig_stress_M, sigma_M, h,\n", + " source_section_scheme, True, yG, scale_x=scale_x)\n", + "S_rect = beam_section.compute_first_moment_of_area(y_discr, b, h, yG)\n", + "tau_V = stst.compute_tau_shear(y_discr, 0, S_rect, Iy, b)\n", + "V_stress_diag = models.stress_diagram(fig_stress_V, tau_V, h, source_section_scheme, scale_x=1)\n", + "\n", + "# plot stress sigma and tau\n", + "sigma_total = sigma_M + sigma_N\n", + "(sigma_stress_diag, neutral_axis) = models.stress_diagram(fig_stress_sigma, sigma_total, h,\n", + " source_section_scheme,True, yG, scale_x=scale_x)\n", + "tau_total = tau_V\n", + "tau_stress_diag = models.stress_diagram(fig_stress_tau, tau_total, h,\n", + " source_section_scheme, scale_x=1)\n", + "\n", + "# plot strain N M\n", + "strain_axial = stst.compute_epsilon_axial(y_discr, sigma_N, E)\n", + "axial_strain_diag = models.strain_diagram(fig_axial_strain, strain_axial, h, source_section_scheme)\n", + "strain_bending = stst.compute_epsilon_bending(y_discr, sigma_M, E)\n", + "bending_strain_diag = models.strain_diagram(fig_bending_strain, strain_bending, h, source_section_scheme)\n", + "\n", + "\n", + "# figures for NVM\n", + "fig_NM_section = figure(**options_stress_strain,\n", + " title=\"N and M at position x\",\n", + " match_aspect=True)\n", + "fig_NM_section.axis.visible = False\n", + "fig_NM_section.grid.grid_line_alpha = 0\n", + "\n", + "fig_V_section = figure(**options_stress_strain,\n", + " title=\"V at position x\",\n", + " match_aspect=True)\n", + "fig_V_section.axis.visible = False\n", + "fig_V_section.grid.grid_line_alpha = 0\n", + "\n", + "# section with NVM\n", + "models.section_diagram(fig_NM_section)\n", + "models.section_diagram(fig_V_section)\n", + "\n", + "# NVM in section\n", + "section_N = models.force_vector(fig_NM_section, 0, 0, 0, 0, 0, 'red')\n", + "section_V = models.force_vector(fig_V_section, 0, 0, 0, 0, 0, 'red')\n", + "(section_M_line, section_M_head, source_section_M) = models.define_curvedArrow(fig_NM_section, 0, 0, 0, size_head=0)\n", + "\n", + "# NVM label in section\n", + "OFFSET_N = 1\n", + "label_N_section = fig_NM_section.text(x=[P*1.1], y=[OFFSET_N], text=[\"\"], text_color=\"red\", text_baseline='bottom')\n", + "label_M_section = fig_NM_section.text(x=[OFFSET_N*6], y=[-OFFSET_N*5], text=[\"\"], text_color=\"red\", text_baseline='top')\n", + "label_V_section = fig_V_section.text(x=[OFFSET_N*5], y=[0], text=[\"\"], text_color=\"red\", text_baseline='middle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update data\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{models.implement_check_stateJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b = dict(source=source,\n", + " s_b=source_beam,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const yG = db['yG'][0]\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b, code=code_change_b)\n", + "\n", + "\n", + "args_slider_h = dict(source=source,\n", + " s_b=source_beam,\n", + " s_ss=source_section_scheme,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag)\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const data_ss = s_ss.data\n", + "const b = db['b'][0]\n", + "const h = cb_obj.value // value of the slider\n", + "const A = compute_area(b, h)\n", + "const Iy = compute_inertia_y(b, h)\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "const yG = compute_centroid_y(h)\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h)\n", + "db['yG'][0] = yG\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "data_ss['y'][1] = h // change the height of the section in the diagrams\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_ss.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head,\n", + " N_diag=N_diag,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "\n", + "// apply the changes\n", + "db['P'][0] = {P}*(1-f)\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_N_diagram(db, N_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_N_diagramJS(discr_NVM)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " V_diag=V_diag,\n", + " M_diag=M_diag,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['q'][0] = q\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_V_diagram(db, V_diag)\n", + "update_M_diagram(db, M_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_update_V_diagramJS(discr_NVM)}\n", + "{sb.implement_update_M_diagramJS(discr_NVM)}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain)}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_scheme,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout),\n", + " slider_b,\n", + " slider_h,\n", + " row(div_geo, div_forces),\n", + " Spacer(height=padding_layout),\n", + " slider_position,\n", + " slider_q,\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P))),\n", + " column(fig_beam,\n", + " Spacer(height=padding_layout),\n", + " fig_N,\n", + " fig_V,\n", + " fig_M)),\n", + " row(column(\n", + " row(fig_NM_section, fig_axial_strain, fig_stress_N, fig_bending_strain, fig_stress_M, fig_stress_sigma),\n", + " row(fig_V_section, Spacer(width=FIG_B_ss), fig_stress_V, Spacer(width=FIG_B_ss), Spacer(width=FIG_B_ss), fig_stress_tau),\n", + " ))\n", + " )],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Simple Beam DEMOs/sb_torsion.ipynb b/Simple Beam DEMOs/sb_torsion.ipynb new file mode 100644 index 0000000..fd90504 --- /dev/null +++ b/Simple Beam DEMOs/sb_torsion.ipynb @@ -0,0 +1,1353 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple beam - Torsion\n", + "In this first notebook, the torsion is presented. Considering the complexity of the problem with this new cross-section geometry and the introduction of the torsion, the focus of the notebook in the stress and strain analysis is placed on the left web." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the packages needed\n", + "import math\n", + "import numpy as np \n", + "from bokeh.layouts import layout, column, row\n", + "from bokeh.models.annotations import Label, Arrow\n", + "from bokeh.models.arrow_heads import VeeHead\n", + "from bokeh.models import Div, CustomJS, Slider, Spacer, Text\n", + "from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup\n", + "from bokeh.plotting import figure, show, ColumnDataSource\n", + "from bokeh.io import output_notebook\n", + "from cienpy import simplebeam as sb\n", + "from cienpy import hollow_rectangular_section as beam_section\n", + "from cienpy import stress_strain_elastic as stst\n", + "from cienpy import models\n", + "from cienpy import javascriptcodes as js\n", + "\n", + "# output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the geometry, uniform load and torsion. Both supports are fixed with respect to the torsion.\n", + "Note that given the graphical nature of the notebook, extreme cases can cause the figures to not be displayed." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the dimensions\n", + "L = 6 # [m]\n", + "h = 200 # [mm]\n", + "b = 100 # [mm]\n", + "t = 10 # [mm]\n", + "q = 4 # [kN/m]\n", + "P = 10 # [kN]\n", + "Mt = 100 # [kNm]\n", + "\n", + "# Choose the material parameters\n", + "E = 200e3 # [MPa]\n", + "\n", + "# compute the internal forces (at x=L)\n", + "discr_NVM = 100\n", + "x_discr = np.linspace(0, L, discr_NVM)\n", + "N_discr = sb.compute_N(x_discr, P)\n", + "V_discr = sb.compute_V(x_discr, q, L)\n", + "M_discr = sb.compute_M(x_discr, q, L)\n", + "T_discr = sb.compute_T(x_discr, Mt, L)\n", + "N = N_discr[-1]\n", + "V = V_discr[-1]\n", + "M = M_discr[-1]\n", + "T = T_discr[-1]\n", + "\n", + "# compute the parameters\n", + "A = beam_section.compute_area(b, h, t) # [mm2]\n", + "Iy = beam_section.compute_inertia_y(b, h, t) # [mm4] strong axis\n", + "Iz = beam_section.compute_inertia_z(b, h, t) # [mm4] weak axis\n", + "yG = beam_section.compute_centroid_y(h)\n", + "y_n_axis = stst.compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "# compute the reactions\n", + "Rx = sb.compute_Rx(P)\n", + "Ry_l = sb.compute_Ry_l(q, L)\n", + "Ry_r = sb.compute_Ry_r(q, L)\n", + "\n", + "# constants for the visualisation\n", + "SCALE = 10\n", + "SCALE_T = 10\n", + "OFFSET_Q = q\n", + "MAX_B = 3*b\n", + "MAX_H = 3*h\n", + "MAX_T = 2*t\n", + "MAX_Q = q/4*5\n", + "\n", + "# store the values in a specific format\n", + "data_beam = dict(\n", + " x=[0, L],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_beam = dict(\n", + " x=[0, L*SCALE],\n", + " y=[0, 0]\n", + ")\n", + "\n", + "data_scheme_q = dict(\n", + " x=[0, 0, L*SCALE, L*SCALE],\n", + " y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],\n", + " x_fade=[0, 0, L*SCALE, L*SCALE]\n", + ")\n", + "\n", + "data_section_scheme = dict(\n", + " x=[0, 0], \n", + " y=[0, h]\n", + ")\n", + "\n", + "initial_position = L\n", + "initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC\n", + "initial_FBD = 0 # right=0 left=1\n", + "data = dict( # stores every useful single variable\n", + " state=[initial_state], \n", + " FBD=[initial_FBD],\n", + " SCALE=[SCALE],\n", + " L=[L],\n", + " b=[b],\n", + " h=[h],\n", + " t=[t],\n", + " E=[E],\n", + " A=[A],\n", + " Iy=[Iy],\n", + " Iz=[Iz],\n", + " yG=[yG],\n", + " y_n_axis=[y_n_axis],\n", + " P=[P],\n", + " x=[initial_position],\n", + " y=[0],\n", + " q=[q],\n", + " Mt=[Mt],\n", + " Rx=[Rx],\n", + " Ry_l=[Ry_l],\n", + " Ry_r=[Ry_r],\n", + " N=[N],\n", + " V=[V],\n", + " M=[M],\n", + " T=[T],\n", + " xF=[L*SCALE]\n", + ")\n", + "\n", + "source_beam = ColumnDataSource(data_beam)\n", + "source_scheme_beam = ColumnDataSource(data_scheme_beam)\n", + "source_scheme_q = ColumnDataSource(data_scheme_q)\n", + "source_section_scheme = ColumnDataSource(data_section_scheme)\n", + "source = ColumnDataSource(data)\n", + "\n", + "# Constants\n", + "FIG_H_B = 200 # height figure beam\n", + "FIG_B_B = 700 # width figure beam\n", + "FIG_H_S = FIG_H_B # height figure scheme\n", + "FIG_B_S = FIG_B_B # width figure scheme\n", + "FIG_H_SEC = 600 # height figure section\n", + "DIV_B_GEO = 170\n", + "DIV_B_FORCES = 170" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the figures, the plots and the widgets (same of Notebook 4 - Stresses and Strains):" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "options = dict(\n", + " toolbar_location=None\n", + ")\n", + "\n", + "# figure for the beam\n", + "paddingx = 0.2*L\n", + "int_x_b = (0-paddingx, L+paddingx)\n", + "int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)\n", + "fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,\n", + " f_h=FIG_H_B, f_b=FIG_B_B)\n", + "\n", + "\n", + "# figure for the cross-section\n", + "fig_section = sb.define_fig_section(MAX_B*0.8, MAX_H*0.8, options, FIG_H_SEC)\n", + "\n", + "# Doge for scale (if not visualized, remove this part because the browser don't support it correctly)\n", + "h_img = 350 # mm\n", + "fig_section.image_url(url=['https://img-10.stickers.cloud/packs/9a805d22-5d64-42f0-ae3c-bf58e080a463/webp/71246027-2154-494f-adcc-eeb814c11dad.webp'], x=-h_img/2, y=-MAX_H/2*1.01, h=h_img, w=h_img)\n", + "fig_section.text(x=[0], y=[-MAX_H/2-h_img*1.05], text_align=\"center\", text=[f\"Doge for scale (h={h_img} mm)\"], text_font_size=\"10px\")\n", + "\n", + "\n", + "# beam\n", + "(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,\n", + " ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)\n", + "\n", + "# section\n", + "section = beam_section.draw_section(fig_section, b, h, t)\n", + "\n", + "\n", + "# show mechanical parameters\n", + "div_geo = Div(width= DIV_B_GEO, \n", + " text=beam_section.div_text_geo(round(h), round(b), round(t), round(L),\n", + " \"{:.2e}\".format(A),\n", + " \"{:.2e}\".format(Iy),\n", + " \"{:.2e}\".format(Iz)))\n", + "\n", + "\n", + "# change geometry\n", + "slider_b = Slider(\n", + " title=\"Change the width b [mm]\",\n", + " start=MAX_T*2+10,\n", + " end=MAX_B,\n", + " step=10,\n", + " value=b\n", + ")\n", + "slider_h = Slider(\n", + " title=\"Change the height h [mm]\",\n", + " start=MAX_T*2+10,\n", + " end=MAX_H,\n", + " step=10,\n", + " value=h\n", + ")\n", + "\n", + "# reference system\n", + "axis_arrow_length = 0.8\n", + "axis_arrow_scale = 100\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis\n", + "fig_section.text(x=[0], y=[axis_arrow_length*axis_arrow_scale*1.7], text=[\"y\"], text_color='gray', text_baseline='middle', angle=math.pi/2)\n", + "models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis\n", + "fig_section.text(x=[-axis_arrow_length*axis_arrow_scale*1.1], y=[0], text=[\"z\"], text_color='gray', text_align='right', text_baseline='middle')\n", + "\n", + "\n", + "# figure for the forces and moments\n", + "fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)\n", + "\n", + "\n", + "# uniform load (beam)\n", + "u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE], width=L, height=q/SCALE,\n", + " fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)\n", + "label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE], text=[\"q\"], text_color=\"blue\")\n", + "\n", + "\n", + "# axial force (beam)\n", + "axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')\n", + "label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/4], text=[\"P\"], text_color=\"green\")\n", + "\n", + "\n", + "# position point\n", + "pos_opt = dict(\n", + " source=source,\n", + " size=10,\n", + " fill_alpha=0.5,\n", + " fill_color=\"magenta\",\n", + " color=\"magenta\",\n", + " alpha=0.5\n", + ")\n", + "beam_position = fig_beam.circle('x', 'y', **pos_opt)\n", + "forces_position = fig_scheme.circle('xF', 'y', **pos_opt)\n", + "\n", + "\n", + "# beam (scheme)\n", + "scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')\n", + "scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)\n", + "# uniform load (scheme)\n", + "scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',\n", + " fill_alpha=0.3, alpha=0.3)\n", + "scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',\n", + " color='navy', fill_alpha=0.3, alpha=0.3)\n", + "# axial force (scheme)\n", + "scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')\n", + "# Reactions (scheme)\n", + "scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')\n", + "scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')\n", + "scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')\n", + "# force N\n", + "scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# force V\n", + "scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')\n", + "# moment M\n", + "(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# change the uniform load q\n", + "slider_q = Slider(\n", + " title=\"Change the uniform load q [kN/m]\",\n", + " start=0.1,\n", + " end=MAX_Q,\n", + " step=0.1,\n", + " value=q\n", + ")\n", + "\n", + "\n", + "# choose position of interest\n", + "slider_position = Slider(\n", + " title=\"Change the position x along the beam [m]\",\n", + " start=0,\n", + " end=L,\n", + " step=0.02,\n", + " value=L\n", + ")\n", + "\n", + "\n", + "# choose left or right FBD\n", + "div_rg_FBD = Div(text=\"Free-body diagram (FBD):\")\n", + "radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)\n", + "\n", + "\n", + "# choose axial force or not\n", + "div_cb_P = Div(text=f\"Axial force P={P} kN (applied)\")\n", + "checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])\n", + "\n", + "\n", + "# show values of forces and moments\n", + "div_forces = Div(width=DIV_B_FORCES, \n", + " text=sb.div_text_forces(P, P, Ry_l, Ry_r, \"No cross section analysed.\", 0, 0, 0))\n", + "\n", + "\n", + "# figures for the diagrams\n", + "options_diag = dict(\n", + " toolbar_location=None,\n", + " x_axis_label=\"Position [m]\",\n", + " plot_width=FIG_B_B,\n", + " x_range=fig_beam.x_range\n", + ")\n", + "fig_N = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Axial force\", \"@y kN\")],\n", + " y_axis_label=\"Axial force N [kN]\",\n", + " plot_height=int(FIG_H_B*0.8),\n", + " title=\"N V M Diagrams\")\n", + "fig_V = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Shear force\", \"@y kN\")],\n", + " y_axis_label=\"Shear force V [kN]\",\n", + " plot_height=int(FIG_H_B*0.8))\n", + "fig_M = figure(**options_diag,\n", + " tooltips= [(\"Position\", \"@x m\"),\n", + " (\"Bending moment\", \"@y kNm\")],\n", + " y_axis_label=\"Bending moment M [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "fig_N.xaxis.visible = False\n", + "fig_V.xaxis.visible = False\n", + "\n", + "\n", + "# plot N V M\n", + "N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)\n", + "V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)\n", + "M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)\n", + "\n", + "\n", + "# point that shows the position that it's analyzed\n", + "N_position = fig_N.circle('x', 'N', **pos_opt)\n", + "V_position = fig_V.circle('x', 'V', **pos_opt)\n", + "M_position = fig_M.circle('x', 'M', **pos_opt)\n", + "\n", + "\n", + "# figures for the stresses and strains\n", + "FIG_B_ss = 200\n", + "FIG_H_ss = 200\n", + "options_stress_strain = dict(\n", + " toolbar_location=None,\n", + " y_axis_label=\"Height h [mm]\",\n", + " plot_width=FIG_B_ss,\n", + " plot_height=FIG_H_ss,\n", + ")\n", + "fig_stress_N = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2099 [MPa]\")\n", + "fig_stress_N.yaxis.visible = False\n", + "fig_axial_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Axial strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2099 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_axial_strain.yaxis.visible = False\n", + "fig_stress_M = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending stress and centroid\",\n", + " y_range=fig_stress_N.y_range,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA}\\u2098 [MPa]\")\n", + "fig_stress_M.yaxis.visible = False\n", + "fig_bending_strain = figure(**options_stress_strain,\n", + " tooltips= [(\"Strain\", \"@x %\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Bending strain\",\n", + " x_axis_label=\"Strain \\N{GREEK SMALL LETTER EPSILON}\\u2098 [%]\",\n", + " y_range=fig_stress_N.y_range)\n", + "fig_bending_strain.yaxis.visible = False\n", + "fig_stress_V = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Shear stress\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU}\\u1d65 [MPa]\")\n", + "fig_stress_V.yaxis.visible = False\n", + "fig_stress_sigma = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER SIGMA} and neutral axis\",\n", + " y_range=fig_stress_N.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER SIGMA} [MPa]\")\n", + "fig_stress_tau = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Total stress \\N{GREEK SMALL LETTER TAU}\",\n", + " y_range=fig_stress_V.y_range,\n", + " y_axis_location=\"right\",\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU} [MPa]\")\n", + "\n", + "\n", + "# plot stress N V M\n", + "discr_stress_strain = 50\n", + "scale_x = 25\n", + "y_discr = np.linspace(0, h, discr_stress_strain)\n", + "sigma_N = stst.compute_sigma_axial(y_discr, N, A)\n", + "N_stress_diag = models.stress_diagram(fig_stress_N, sigma_N, h,\n", + " source_section_scheme, scale_x=scale_x/10)\n", + "sigma_M = stst.compute_sigma_bending(y_discr, 0, Iy, yG)\n", + "(M_stress_diag, centroid) = models.stress_diagram(fig_stress_M, sigma_M, h,\n", + " source_section_scheme, True, yG, scale_x=scale_x)\n", + "S_rect = beam_section.compute_first_moment_of_area(y_discr, b, h, t, yG)\n", + "tau_V = stst.compute_tau_shear(y_discr, 0, S_rect, Iy, b)\n", + "V_stress_diag = models.stress_diagram(fig_stress_V, tau_V, h, source_section_scheme, scale_x=1)\n", + "\n", + "\n", + "# plot stress sigma and tau\n", + "sigma_total = sigma_M + sigma_N\n", + "(sigma_stress_diag, neutral_axis) = models.stress_diagram(fig_stress_sigma, sigma_total, h,\n", + " source_section_scheme,True, yG, scale_x=scale_x)\n", + "tau_total = tau_V\n", + "tau_stress_diag = models.stress_diagram(fig_stress_tau, tau_total, h,\n", + " source_section_scheme, scale_x=1)\n", + "\n", + "# plot strain N M\n", + "strain_axial = stst.compute_epsilon_axial(y_discr, sigma_N, E)\n", + "axial_strain_diag = models.strain_diagram(fig_axial_strain, strain_axial, h, source_section_scheme)\n", + "strain_bending = stst.compute_epsilon_bending(y_discr, sigma_M, E)\n", + "bending_strain_diag = models.strain_diagram(fig_bending_strain, strain_bending, h, source_section_scheme)\n", + "\n", + "\n", + "# figures for NVM\n", + "fig_NM_section = figure(**options_stress_strain,\n", + " title=\"N and M at position x\",\n", + " match_aspect=True)\n", + "fig_NM_section.axis.visible = False\n", + "fig_NM_section.grid.grid_line_alpha = 0\n", + "\n", + "fig_V_section = figure(**options_stress_strain,\n", + " title=\"V at position x\",\n", + " match_aspect=True)\n", + "fig_V_section.axis.visible = False\n", + "fig_V_section.grid.grid_line_alpha = 0\n", + "\n", + "\n", + "# section with NVM\n", + "models.section_diagram(fig_NM_section)\n", + "models.section_diagram(fig_V_section)\n", + "\n", + "\n", + "# NVM in section\n", + "section_N = models.force_vector(fig_NM_section, 0, 0, 0, 0, 0, 'red')\n", + "section_V = models.force_vector(fig_V_section, 0, 0, 0, 0, 0, 'red')\n", + "(section_M_line, section_M_head, source_section_M) = models.define_curvedArrow(fig_NM_section, 0, 0, 0, size_head=0)\n", + "\n", + "\n", + "# NVM label in section\n", + "OFFSET_N = 1\n", + "label_N_section = fig_NM_section.text(x=[P*1.1], y=[OFFSET_N], text=[\"\"], text_color=\"red\", text_baseline='bottom')\n", + "label_M_section = fig_NM_section.text(x=[OFFSET_N*6], y=[-OFFSET_N*5], text=[\"\"], text_color=\"red\", text_baseline='top')\n", + "label_V_section = fig_V_section.text(x=[OFFSET_N*5], y=[OFFSET_N*4], text=[\"\"], text_color=\"red\", text_baseline='middle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define the new figures, renderers and widgets:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# applied torsion Mt\n", + "str_Mt = \"M\\N{LATIN SUBSCRIPT SMALL LETTER T}\"\n", + "div_cb_T = Div(text=f\"Torsion {str_Mt}={Mt} kNm (applied)\")\n", + "checkbox_T = CheckboxButtonGroup(labels=[f'Apply or remove torsion {str_Mt}'], active=[0])\n", + "\n", + "\n", + "# torsion diagram\n", + "fig_M.plot_height = int(FIG_H_B*0.8)\n", + "fig_M.xaxis.visible = False\n", + "fig_T = figure(**options_diag,\n", + " tooltips= [(\"Position:\", \"@x m\"),\n", + " (\"Torsion:\", \"@y kNm\")],\n", + " y_axis_label=\"Torsion T [kNm]\",\n", + " plot_height=FIG_H_B)\n", + "\n", + "\n", + "# change geometry (thickness)\n", + "slider_t = Slider(\n", + " title=\"Change the thicknes t [mm]\",\n", + " start=2,\n", + " end=MAX_T,\n", + " step=1,\n", + " value=t\n", + ")\n", + "\n", + "\n", + "# plot T\n", + "T_diag = models.NVM_diagram(fig_T, x_discr, T_discr, L, source_beam)\n", + "\n", + "\n", + "# point that shows the position that it's analyzed\n", + "T_position = fig_T.circle('x', 'T', **pos_opt)\n", + "\n", + "\n", + "# figure for the stress tau_T\n", + "fig_stress_T = figure(**options_stress_strain,\n", + " tooltips= [(\"Stress\", \"@x MPa\"),\n", + " (\"Height\", \"@y mm\")],\n", + " title=\"Torsional stress\",\n", + " y_range=fig_stress_V.y_range,\n", + " x_axis_label=\"Stress \\N{GREEK SMALL LETTER TAU}\\N{LATIN SUBSCRIPT SMALL LETTER T} [MPa]\")\n", + "fig_stress_T.yaxis.visible = False\n", + "\n", + "\n", + "# torsion in the section\n", + "(section_torsion_line, section_torsion_head, section_torsion_source) = models.define_curvedArrow(fig_section, 0, T*4/SCALE_T, abs(T*3/SCALE_T), size_head=20)\n", + "\n", + "\n", + "# moment Mt in beam\n", + "PIXEL2UNIT_BEAM = 100\n", + "(beam_torsion_line, beam_torsion_head, source_beam_torsion) = models.define_doubleArrow(fig_beam, L/2, L/2+Mt/SCALE/10, 0, 0,\n", + " arrow_color=\"green\", pixel2unit=PIXEL2UNIT_BEAM)\n", + "# label\n", + "label_Mt_force = fig_beam.text(x=[L/2+Mt/2/SCALE/SCALE_T], y=[OFFSET_Q/4/SCALE/SCALE_T], text=[str_Mt], text_color=\"green\")\n", + "\n", + "\n", + "# add torsion in section stress\n", + "T_DOUBLE_HEAD_SIZE = 10\n", + "(section_T_line, section_T_head, section_T_source) = models.define_doubleArrow(fig_V_section, OFFSET_N*4-T/SCALE_T, OFFSET_N*4, 0, 0, size_head=T_DOUBLE_HEAD_SIZE)\n", + "# label\n", + "label_T_section = fig_V_section.text(x=[Mt*1.1/SCALE_T], y=[OFFSET_N], text=[\"T\"], text_color=\"red\", text_baseline='bottom')\n", + "\n", + "\n", + "# tau stress torsion\n", + "tau_T = beam_section.compute_tau_torsion(y_discr, T, b, h, t)\n", + "T_stress_diag = models.stress_diagram(fig_stress_T, tau_T, h, source_section_scheme, scale_x=1)\n", + "\n", + "# Easter egg\n", + "EasterEgg1 = fig_N.text(x=[2], y=[-4], text=\"\", text_color=\"purple\", text_font_size=\"10px\", angle=math.pi/10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configure the logics:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "args_slider_pos = dict(source=source,\n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " s_M=source_M,\n", + " arr_head=scheme_M_head,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section,\n", + " section_T_line=section_T_line,\n", + " section_T_head=section_T_head,\n", + " section_T_source=section_T_source,\n", + " section_torsion_head=section_torsion_head,\n", + " section_torsion_source=section_torsion_source,\n", + " label_T_section=label_T_section,\n", + " div_T=div_cb_T,\n", + " T_stress_diag=T_stress_diag)\n", + "code_slider_pos = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const FBD = db['FBD'][0]\n", + "const pos = cb_obj.value\n", + "const q = db['q'][0]\n", + "const L = db['L'][0]\n", + "const Mt = db['Mt'][0]\n", + "\n", + "// update data\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['T'][0] = compute_T(pos, Mt, L)\n", + "db['x'][0] = pos\n", + "\n", + "// check state\n", + "check_state(db)\n", + "\n", + "// update:\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "update_T_section(db, section_torsion_head, section_torsion_source, section_T_line, section_T_head, section_T_source, div_T, label_T_section)\n", + "update_torsional_stress(db, T_stress_diag)\n", + "\n", + "// apply the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{models.implement_check_stateJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain, hollow_rectangular_section=True)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{sb.implement_update_T_sectionJS(scale_T=SCALE_T)}\n", + "{js.implement_update_doubleArrowJS()}\n", + "{sb.implement_compute_TJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "{beam_section.implement_update_torsional_stressJS(discr_stress_strain)}\n", + "\"\"\"\n", + "updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)\n", + "\n", + "\n", + "args_slider_b = dict(source=source,\n", + " s_b=source_beam,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " T_stress_diag=T_stress_diag,\n", + " div_P=div_cb_P)\n", + "code_change_b = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const b = cb_obj.value // value of the slider\n", + "const h = db['h'][0]\n", + "const t = db['t'][0]\n", + "const A = compute_area(b, h, t)\n", + "const Iy = compute_inertia_y(b, h, t)\n", + "const yG = db['yG'][0]\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "\n", + "// Easter egg\n", + "const str_Doge = \" such width\"\n", + "const str_tmp = div_P.text\n", + "if (b == {MAX_B}) {{\n", + " div_P.text = str_tmp+str_Doge\n", + "}} else {{\n", + " div_P.text = str_tmp.replace(str_Doge, '')\n", + "}}\n", + "\n", + "// apply the changes\n", + "db['b'][0] = b\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h, t)\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_torsional_stress(db, T_stress_diag)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain, hollow_rectangular_section=True)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "{beam_section.implement_update_torsional_stressJS(discr_stress_strain)}\n", + "\"\"\"\n", + "update_b = CustomJS(args=args_slider_b, code=code_change_b)\n", + "\n", + "\n", + "args_slider_h = dict(source=source,\n", + " s_b=source_beam,\n", + " s_ss=source_section_scheme,\n", + " div=div_geo, \n", + " section=section,\n", + " support_r=support_r,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " T_stress_diag=T_stress_diag,\n", + " div_T=div_cb_T,\n", + " EE1=EasterEgg1)\n", + "code_change_h = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const data_ss = s_ss.data\n", + "const b = db['b'][0]\n", + "const t = db['t'][0]\n", + "const h = cb_obj.value // value of the slider\n", + "const A = compute_area(b, h, t)\n", + "const Iy = compute_inertia_y(b, h, t)\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "const yG = compute_centroid_y(h)\n", + "\n", + "// Easter egg\n", + "/*const str_Doge = \" much wow\"\n", + "const str_tmp = div_T.text\n", + "if (h == {MAX_H}) {{\n", + " div_T.text = str_tmp+str_Doge\n", + "}} else {{\n", + " div_T.text = str_tmp.replace(str_Doge, '')\n", + "}}*/\n", + "if (h == {MAX_H}) {{\n", + " EE1.glyph.text = \"much wow\"\n", + "}} else {{\n", + " EE1.glyph.text = \"\"\n", + "}}\n", + "\n", + "// apply the changes\n", + "db['h'][0] = h\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h, t)\n", + "db['yG'][0] = yG\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "data_ss['y'][1] = h // change the height of the section in the diagrams\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_torsional_stress(db, T_stress_diag)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_ss.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain, hollow_rectangular_section=True)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "{beam_section.implement_update_torsional_stressJS(discr_stress_strain)}\n", + "\"\"\"\n", + "update_h = CustomJS(args=args_slider_h, code=code_change_h)\n", + "\n", + "\n", + "args_checkbox_P = dict(source=source,\n", + " s_M=source_M,\n", + " div_P=div_cb_P,\n", + " div_f=div_forces,\n", + " fP=scheme_axial_force, \n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r, \n", + " fN=scheme_N,\n", + " fV=scheme_V, \n", + " arr_head=scheme_M_head,\n", + " N_diag=N_diag,\n", + " neutral_axis=neutral_axis,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_checkbox_P = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox P\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "\n", + "// apply the changes\n", + "db['P'][0] = {P}*(1-f)\n", + "db['N'][0] = compute_N(db['P'][0])\n", + "db['Rx'][0] = compute_Rx(db['P'][0])\n", + "\n", + "// update\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_N_diagram(db, N_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_compute_RxJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_compute_NJS()}\n", + "{sb.implement_update_N_diagramJS(discr_NVM)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "\"\"\"\n", + "update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)\n", + "\n", + "\n", + "args_radiogroup_FBD = dict(source=source, \n", + " s_sb=source_scheme_beam,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M, \n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N, \n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " tau_stress_diag=tau_stress_diag)\n", + "code_radiogroup_FBD = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const FBD = cb_obj.active\n", + "const data_sb = s_sb.data\n", + "const data_q = s_q.data\n", + "const pos = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['FBD'][0] = FBD\n", + "\n", + "// update\n", + "check_state(db)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_scheme_position(db, data_sb, data_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "s_sb.change.emit()\n", + "s_q.change.emit()\n", + "\n", + "{models.implement_check_stateJS()}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{sb.implement_update_scheme_positionJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "\"\"\"\n", + "update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)\n", + "\n", + "\n", + "args_slider_q = dict(source=source,\n", + " s_q=source_scheme_q,\n", + " s_M=source_M,\n", + " div_f=div_forces,\n", + " div_P=div_cb_P,\n", + " fP=scheme_axial_force,\n", + " fRx=scheme_Rx_l,\n", + " fRyl=scheme_Ry_l,\n", + " fRyr=scheme_Ry_r,\n", + " fN=scheme_N,\n", + " fV=scheme_V,\n", + " arr_head=scheme_M_head,\n", + " V_diag=V_diag,\n", + " M_diag=M_diag,\n", + " centroid=centroid,\n", + " neutral_axis=neutral_axis,\n", + " V_stress_diag=V_stress_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " section_N=section_N,\n", + " section_V=section_V,\n", + " section_M_head=section_M_head,\n", + " s_section_M=source_section_M,\n", + " label_N_section=label_N_section,\n", + " label_V_section=label_V_section,\n", + " label_M_section=label_M_section)\n", + "code_slider_q = f\"\"\"\n", + "// retrieve data\n", + "const db = source.data\n", + "const q = cb_obj.value\n", + "const pos = db['x'][0]\n", + "const L = db['L'][0]\n", + "\n", + "// update q\n", + "db['q'][0] = q\n", + "db['V'][0] = compute_V(pos, q, L)\n", + "db['M'][0] = compute_M(pos, q, L)\n", + "db['Ry_l'][0] = compute_Ry_l(q, L)\n", + "db['Ry_r'][0] = compute_Ry_r(q, L)\n", + "\n", + "// update\n", + "update_u_load(db, s_q)\n", + "update_reactions(db, fRx, fRyl, fRyr)\n", + "update_external_forces(db, fP, div_P)\n", + "update_V_diagram(db, V_diag)\n", + "update_M_diagram(db, M_diag)\n", + "update_internal_forces(db, fN, fV, arr_head, s_M)\n", + "update_div_forces(db, div_f)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_NVM_section(db, section_N, section_V, section_M_head, s_section_M, label_N_section, label_V_section, label_M_section)\n", + "\n", + "// apply changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_arrowJS()}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_parabolaJS()}\n", + "{js.implement_arrow_alphaJS()}\n", + "{js.implement_update_arrowJS()}\n", + "{sb.implement_compute_VJS()}\n", + "{sb.implement_compute_MJS()}\n", + "{sb.implement_compute_Ry_lJS()}\n", + "{sb.implement_compute_Ry_rJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{sb.implement_update_V_diagramJS(discr_NVM)}\n", + "{sb.implement_update_M_diagramJS(discr_NVM)}\n", + "{sb.implement_update_reactionsJS()}\n", + "{sb.implement_update_external_forcesJS()}\n", + "{sb.implement_update_u_loadJS(OFFSET_Q)}\n", + "{sb.implement_update_internal_forcesJS()}\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain, hollow_rectangular_section=True)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{beam_section.implement_compute_centroid_yJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{sb.implement_update_div_forcesJS()}\n", + "{js.implement_update_NVM_sectionJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "\"\"\"\n", + "update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)\n", + "\n", + "\n", + "args_checkbox_T = dict(source=source,\n", + " T_diag=T_diag,\n", + " div_T=div_cb_T,\n", + " label_T_section=label_T_section,\n", + " section_T_line=section_T_line,\n", + " section_T_head=section_T_head,\n", + " section_T_source=section_T_source,\n", + " section_torsion_head=section_torsion_head,\n", + " section_torsion_source=section_torsion_source,\n", + " neutral_axis=neutral_axis,\n", + " sigma_stress_diag=sigma_stress_diag,\n", + " tau_stress_diag=tau_stress_diag,\n", + " T_stress_diag=T_stress_diag)\n", + "code_checkbox_T = f\"\"\"\n", + "// retrieve var from the object that uses callback\n", + "var f = cb_obj.active // checkbox Mt\n", + "if (f.length==0) f = [1]\n", + "const db = source.data\n", + "const L = db['L'][0]\n", + "const x = db['x'][0]\n", + "\n", + "// apply the changes\n", + "db['Mt'][0] = {Mt}*(1-f)\n", + "db['T'][0] = compute_T(x, db['Mt'][0], L)\n", + "\n", + "// update\n", + "update_torsional_stress(db, T_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "update_T_diagram(db, T_diag)\n", + "update_T_section(db, section_torsion_head, section_torsion_source, section_T_line, section_T_head, section_T_source, div_T, label_T_section)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "// declare functions\n", + "{js.implement_update_curvedArrowJS()}\n", + "{js.implement_update_doubleArrowJS()}\n", + "{js.implement_arrow_growthJS()}\n", + "{sb.implement_update_T_sectionJS(scale_T=SCALE_T)}\n", + "{sb.implement_compute_TJS()}\n", + "{sb.implement_update_T_diagramJS(discr_NVM)}\n", + "{js.implement_linspaceJS()}\n", + "{js.implement_update_NVM_diagramJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{beam_section.implement_update_torsional_stressJS(discr_stress_strain)}\n", + "\"\"\"\n", + "update_checkbox_T = CustomJS(args=args_checkbox_T, code=code_checkbox_T)\n", + "\n", + "\n", + "args_slider_t = dict(source=source,\n", + " div=div_geo,\n", + " section=section,\n", + " N_stress_diag=N_stress_diag,\n", + " axial_strain_diag=axial_strain_diag,\n", + " M_stress_diag=M_stress_diag,\n", + " bending_strain_diag=bending_strain_diag,\n", + " centroid=centroid,\n", + " V_stress_diag=V_stress_diag,\n", + " sigma_stress_diag=sigma_stress_diag, \n", + " tau_stress_diag=tau_stress_diag,\n", + " neutral_axis=neutral_axis,\n", + " T_stress_diag=T_stress_diag)\n", + "code_change_t = f\"\"\"\n", + "// retrieve data used\n", + "const db = source.data\n", + "const t = cb_obj.value // value of the slider\n", + "const b = db['b'][0]\n", + "const h = db['h'][0]\n", + "const A = compute_area(b, h, t)\n", + "const Iy = compute_inertia_y(b, h, t)\n", + "const yG = db['yG'][0]\n", + "const N = db['N'][0]\n", + "const M = db['M'][0]\n", + "\n", + "// apply the changes\n", + "db['t'][0] = t\n", + "db['A'][0] = A\n", + "db['Iy'][0] = Iy\n", + "db['Iz'][0] = compute_inertia_z(b, h, t)\n", + "db['y_n_axis'][0] = compute_neutral_axis(N, A, Iy, M, yG)\n", + "\n", + "// update\n", + "update_div_geo(db, div)\n", + "update_section(db, section)\n", + "update_axial_stress_strain(db, N_stress_diag, axial_strain_diag)\n", + "update_bending_stress_strain(db, M_stress_diag, bending_strain_diag, centroid)\n", + "update_shear_stress(db, V_stress_diag)\n", + "update_torsional_stress(db, T_stress_diag)\n", + "update_total_stress(db, sigma_stress_diag, tau_stress_diag, neutral_axis)\n", + "\n", + "// emit the changes\n", + "source.change.emit()\n", + "\n", + "{beam_section.implement_update_div_geoJS()}\n", + "{beam_section.implement_update_sectionJS()}\n", + "{beam_section.implement_compute_areaJS()}\n", + "{beam_section.implement_compute_inertia_yJS()}\n", + "{beam_section.implement_compute_inertia_zJS()}\n", + "{stst.implement_compute_neutral_axisJS()}\n", + "{js.implement_update_axial_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_bending_stress_strainJS(discr_stress_strain)}\n", + "{js.implement_update_shear_stressJS(discr_stress_strain, hollow_rectangular_section=True)}\n", + "{js.implement_update_total_stressJS(discr_stress_strain, T_opt=True, hollow_rectangular_section=True)}\n", + "{js.implement_linspaceJS()}\n", + "{stst.implement_compute_epsilon_axialJS()}\n", + "{stst.implement_compute_epsilon_bendingJS()}\n", + "{stst.implement_compute_sigma_axialJS()}\n", + "{js.implement_update_stress_diagramJS()}\n", + "{js.implement_update_strain_diagramJS()}\n", + "{stst.implement_compute_sigma_bendingJS()}\n", + "{stst.implement_compute_total_sigmaJS()}\n", + "{stst.implement_compute_total_tauJS()}\n", + "{beam_section.implement_compute_first_moment_of_areaJS()}\n", + "{beam_section.implement_compute_first_moment_of_area_implicitJS()}\n", + "{stst.implement_compute_tau_shearJS()}\n", + "{beam_section.implement_compute_tau_torsionJS()}\n", + "{beam_section.implement_update_torsional_stressJS(discr_stress_strain)}\n", + "\"\"\"\n", + "update_t = CustomJS(args=args_slider_t, code=code_change_t)\n", + "\n", + "\n", + "\n", + "# apply the logics\n", + "slider_b.js_on_change('value', update_b)\n", + "slider_h.js_on_change('value', update_h)\n", + "slider_position.js_on_change('value', updade_slider_pos)\n", + "checkbox_P.js_on_click(update_checkbox_P)\n", + "radiogroup_FBD.js_on_click(update_radiogroup_FBD)\n", + "slider_q.js_on_change('value', update_slider_q)\n", + "slider_t.js_on_change('value', update_t)\n", + "checkbox_T.js_on_click(update_checkbox_T)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Build the layout and show the figures. Note that the forces in the scheme are updated after moving the position of the point with the slider.\n", + "Note that the value of the forces and moments shown below represents the intensity, thus is always positive. The direction is given by the vector in the scheme." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name. This could either be due to a misspelling or typo, or due to an expected column being missing. : key \"text\" value \"\" [renderer: GlyphRenderer(id='6528', ...)]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening in existing browser session.\n" + ] + } + ], + "source": [ + "padding_layout = 10\n", + "layout1 = layout([\n", + " [column(row(column(fig_scheme,\n", + " row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout*3),\n", + " slider_b,\n", + " slider_h,\n", + " slider_t,\n", + " # row(div_geo, div_forces),\n", + " slider_position,\n", + " slider_q,\n", + " Spacer(height=padding_layout*3),\n", + " div_rg_FBD,\n", + " radiogroup_FBD,\n", + " div_cb_P,\n", + " checkbox_P,\n", + " Spacer(height=padding_layout*3),\n", + " div_cb_T,\n", + " checkbox_T))),\n", + " column(fig_beam,\n", + " Spacer(height=padding_layout),\n", + " fig_N,\n", + " fig_V,\n", + " fig_M,\n", + " fig_T)),\n", + " row(column(\n", + " row(fig_NM_section, fig_axial_strain, fig_stress_N, fig_bending_strain, fig_stress_M, fig_stress_sigma),\n", + " row(fig_V_section, Spacer(width=FIG_B_ss), fig_stress_V, Spacer(width=FIG_B_ss), fig_stress_T, fig_stress_tau),\n", + " ))\n", + " ),\n", + " ],\n", + "])\n", + "\n", + "show(layout1)" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "f29f3a16a5c47811d2900cf82e6584cc83572ddcd5db25d9cf9bef77823b3d45" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}