Page MenuHomec4science

hidden_code_nb_diagrams.py
No OneTemporary

File Metadata

Created
Fri, May 3, 21:50

hidden_code_nb_diagrams.py

import math
import numpy as np
from bokeh.layouts import layout, column, row
from bokeh.models.annotations import Label, Arrow
from bokeh.models.arrow_heads import VeeHead
from bokeh.models import Div, CustomJS, Slider, Spacer, Text
from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup
from bokeh.plotting import figure, show, ColumnDataSource
from bokeh.io import output_notebook
from cienpy import simplebeam as sb
from cienpy import rectangular_section as beam_section
from cienpy import models
from cienpy import javascriptcodes as js
output_notebook()
def main_code(L, h, b, A, Iy, Iz, q, P, N, V, M, Rx, Ry_l, Ry_r, discr_NVM, x_discr, N_discr, V_discr, M_discr):
########################################################
# Initialisation
########################################################
# constants for the visualisation
SCALE = 10
OFFSET_Q = q
MAX_B = 3*b
MAX_H = 3*h
MAX_Q = q/4*5
# store the values in a specific format
data_beam = dict(
x=[0, L],
y=[0, 0]
)
data_scheme_beam = dict(
x=[0, L*SCALE],
y=[0, 0]
)
data_scheme_q = dict(
x=[0, 0, L*SCALE, L*SCALE],
y=[OFFSET_Q, OFFSET_Q+q, OFFSET_Q+q, OFFSET_Q],
x_fade=[0, 0, L*SCALE, L*SCALE]
)
initial_position = L
initial_state = 'IDLE' # possible cases: IDLE, R_SEC, L_SEC
initial_FBD = 0 # right=0 left=1
data = dict( # stores every useful single variable
state=[initial_state],
FBD=[initial_FBD],
SCALE=[SCALE],
L=[L],
b=[b],
h=[h],
A=[A],
Iy=[Iy],
Iz=[Iz],
P=[P],
x=[initial_position],
y=[0],
q=[q],
Rx=[Rx],
Ry_l=[Ry_l],
Ry_r=[Ry_r],
N=[N],
V=[V],
M=[M],
xF=[L*SCALE]
)
source_beam = ColumnDataSource(data_beam)
source_scheme_beam = ColumnDataSource(data_scheme_beam)
source_scheme_q = ColumnDataSource(data_scheme_q)
source = ColumnDataSource(data)
########################################################
# Define figures, widgets and renderers as from the previous notebook
########################################################
FIG_H_B = 200 # height figure beam
FIG_B_B = 700 # width figure beam
FIG_H_S = FIG_H_B # height figure scheme
FIG_B_S = FIG_B_B # width figure scheme
FIG_H_SEC = 600 # height figure section
options = dict(
toolbar_location=None
)
# figure for the beam
paddingx = 0.2*L
int_x_b = (0-paddingx, L+paddingx)
int_y_b = (-OFFSET_Q/SCALE, (MAX_Q+OFFSET_Q)/SCALE)
fig_beam = sb.define_fig_beam(int_x_b, int_y_b, options,
f_h=FIG_H_B, f_b=FIG_B_B)
# figure for the cross-section
fig_section = sb.define_fig_section(MAX_B, MAX_H*0.8, options, FIG_H_SEC)
# beam
(beam, support_l, support_r) = sb.draw_beam(fig_beam, source_beam, L,
ratio = (int_y_b[1]-int_y_b[0])/FIG_H_B*100)
# section
section = beam_section.draw_section(fig_section, b, h)
# show mechanical parameters
div_geo = Div(text=beam_section.div_text_geo(round(h), round(b), round(L),
"{:.2e}".format(A),
"{:.2e}".format(Iy),
"{:.2e}".format(Iz)))
# change geometry
slider_b = Slider(
title="Change the width b [mm]",
start=10,
end=MAX_B,
step=10,
value=b
)
slider_h = Slider(
title="Change the height h [mm]",
start=20,
end=MAX_H,
step=20,
value=h
)
# reference system
axis_arrow_length = 0.8
axis_arrow_scale = 100
models.force_vector(fig_section, axis_arrow_length*10, 0, 0, 0, axis_arrow_length*axis_arrow_scale*1.6, 'gray') # y axis
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)
models.force_vector(fig_section, axis_arrow_length*10, 0, -axis_arrow_length*axis_arrow_scale, 0, 0, 'gray') # z axis
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')
# figure for the forces and moments
fig_scheme = sb.define_figure_scheme(L, SCALE, MAX_Q, OFFSET_Q, options, FIG_H_S, FIG_B_S)
# uniform load (beam)
u_load = fig_beam.rect([L/2], [(q/2+OFFSET_Q)/SCALE], width=L, height=q/SCALE,
fill_color='blue', color='navy', fill_alpha=0.6, alpha=0.6)
label_u_load = fig_beam.text(x=[-0.2], y=[OFFSET_Q/SCALE], text=["q"], text_color="blue")
# axial force (beam)
axial_force = models.force_vector(fig_beam, P, L+P/SCALE, L, 0, 0, 'green')
label_P_force = fig_beam.text(x=[L+P/2/SCALE], y=[OFFSET_Q/SCALE/2], text=["P"], text_color="green")
# position point
pos_opt = dict(
source=source,
size=10,
fill_alpha=0.5,
fill_color="magenta",
color="magenta",
alpha=0.5
)
beam_position = fig_beam.circle('x', 'y', **pos_opt)
forces_position = fig_scheme.circle('xF', 'y', **pos_opt)
# beam (scheme)
scheme_beam = fig_scheme.line('x', 'y', source=source_scheme_beam, line_width=2, color='black')
scheme_fade_beam = fig_scheme.line(x=[0, L*SCALE], y=[0, 0], line_width=2, color='black', alpha=0.2)
# uniform load (scheme)
scheme_u_load = fig_scheme.patch('x', 'y', source=source_scheme_q, fill_color='blue', color='navy',
fill_alpha=0.3, alpha=0.3)
scheme_fade_u_load = fig_scheme.patch('x_fade', 'y', source=source_scheme_q, fill_color='blue',
color='navy', fill_alpha=0.3, alpha=0.3)
# axial force (scheme)
scheme_axial_force = models.force_vector(fig_scheme, P, L*SCALE+P, L*SCALE, 0, 0, 'green')
# Reactions (scheme)
scheme_Ry_r = models.force_vector(fig_scheme, Ry_r, L*SCALE, L*SCALE, -Ry_r, 0, 'orange')
scheme_Ry_l = models.force_vector(fig_scheme, Ry_l, 0, 0, -Ry_l, 0, 'orange')
scheme_Rx_l = models.force_vector(fig_scheme, Rx, -Rx, 0, 0, 0, 'orange')
# force N
scheme_N = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')
# force V
scheme_V = models.force_vector(fig_scheme, 0, 0, 0, 0, 0, 'red')
# moment M
(scheme_M_line, scheme_M_head, source_M) = models.define_curvedArrow(fig_scheme, 0, 0, 0, size_head=0)
# change the uniform load q
slider_q = Slider(
title="Change the uniform load q [kN/m]",
start=0.1,
end=MAX_Q,
step=0.1,
value=q
)
# choose position of interest
slider_position = Slider(
title="Change the position x along the beam [m]",
start=0,
end=L,
step=0.02,
value=L
)
# choose left or right FBD
div_rg_FBD = Div(text="Free-body diagram (FBD):")
radiogroup_FBD = RadioButtonGroup(labels=['Right-hand', 'Left-hand'], active=initial_FBD)
# choose axial force or not
div_cb_P = Div(text=f"Axial force P={P} kN (applied)")
checkbox_P = CheckboxButtonGroup(labels=['Apply or remove axial force P'], active=[0])
# show values of forces and moments
div_forces = Div(text=sb.div_text_forces(P, P, Ry_l, Ry_r, "No cross section analysed.", 0, 0, 0))
########################################################
# Define the new figures, widgets and renderers
########################################################
# figures for the diagrams
options_diag = dict(
toolbar_location=None,
x_axis_label="Position [m]",
plot_width=FIG_B_B,
x_range=fig_beam.x_range
)
fig_N = figure(**options_diag,
tooltips= [("Position", "@x m"),
("Axial force", "@y kN")],
y_axis_label="Axial force N [kN]",
plot_height=int(FIG_H_B*0.8),
title="N V M Diagrams")
fig_V = figure(**options_diag,
tooltips= [("Position", "@x m"),
("Shear force", "@y kN")],
y_axis_label="Shear force V [kN]",
plot_height=int(FIG_H_B*0.8))
fig_M = figure(**options_diag,
tooltips= [("Position", "@x m"),
("Bending moment", "@y kNm")],
y_axis_label="Bending moment M [kNm]",
plot_height=FIG_H_B)
fig_N.xaxis.visible = False
fig_V.xaxis.visible = False
# plot N V M
N_diag = models.NVM_diagram(fig_N, x_discr, N_discr, L, source_beam)
V_diag = models.NVM_diagram(fig_V, x_discr, V_discr, L, source_beam)
M_diag = models.NVM_diagram(fig_M, x_discr, M_discr, L, source_beam)
# point that shows the position that it's analyzed
N_position = fig_N.circle('x', 'N', **pos_opt)
V_position = fig_V.circle('x', 'V', **pos_opt)
M_position = fig_M.circle('x', 'M', **pos_opt)
########################################################
# Configurethe logics
########################################################
args_slider_pos = dict(source=source,
s_sb=source_scheme_beam,
s_q=source_scheme_q,
div_P=div_cb_P,
div_f=div_forces,
fP=scheme_axial_force,
fRx=scheme_Rx_l,
fRyl=scheme_Ry_l,
fRyr=scheme_Ry_r,
fN=scheme_N,
fV=scheme_V,
s_M=source_M,
arr_head=scheme_M_head)
code_slider_pos = f"""
// retrieve data
const db = source.data
const data_sb = s_sb.data
const data_q = s_q.data
const FBD = db['FBD'][0]
const pos = cb_obj.value
const q = db['q'][0]
const L = db['L'][0]
// update data
db['N'][0] = compute_N(db['P'][0])
db['V'][0] = compute_V(pos, q, L)
db['M'][0] = compute_M(pos, q, L)
db['x'][0] = pos
// check state
check_state(db)
// update:
update_internal_forces(db, fN, fV, arr_head, s_M)
update_scheme_position(db, data_sb, data_q)
update_reactions(db, fRx, fRyl, fRyr)
update_external_forces(db, fP, div_P)
update_div_forces(db, div_f)
// apply the changes
source.change.emit()
s_sb.change.emit()
s_q.change.emit()
// declare functions
{sb.implement_compute_NJS()}
{sb.implement_compute_VJS()}
{sb.implement_compute_MJS()}
{sb.implement_update_internal_forcesJS()}
{sb.implement_update_scheme_positionJS()}
{sb.implement_update_reactionsJS()}
{sb.implement_update_external_forcesJS()}
{sb.implement_update_div_forcesJS()}
{js.implement_linspaceJS()}
{js.implement_parabolaJS()}
{js.implement_arrow_alphaJS()}
{js.implement_update_arrowJS()}
{js.implement_arrow_growthJS()}
{js.implement_update_curvedArrowJS()}
{js.implement_update_NVM_diagramJS()}
{models.implement_check_stateJS()}
"""
updade_slider_pos = CustomJS(args=args_slider_pos, code=code_slider_pos)
args_slider_b_h = dict(source=source,
s_b=source_beam,
div=div_geo,
section=section,
support_r=support_r)
code_change_b = f"""
// retrieve data used
const db = source.data
const b = cb_obj.value // value of the slider
const h = db['h'][0]
const A = compute_area(b, h)
const Iy = compute_inertia_y(b, h)
// apply the changes
db['b'][0] = b
db['A'][0] = A
db['Iy'][0] = Iy
db['Iz'][0] = compute_inertia_z(b, h)
// update
update_div_geo(db, div)
update_section(db, section)
// emit the changes
source.change.emit()
{beam_section.implement_update_div_geoJS()}
{beam_section.implement_update_sectionJS()}
{beam_section.implement_compute_areaJS()}
{beam_section.implement_compute_inertia_yJS()}
{beam_section.implement_compute_inertia_zJS()}
"""
update_b = CustomJS(args=args_slider_b_h, code=code_change_b)
code_change_h = f"""
// retrieve data used
const db = source.data
const b = db['b'][0]
const h = cb_obj.value // value of the slider
const A = compute_area(b, h)
const Iy = compute_inertia_y(b, h)
// apply the changes
db['h'][0] = h
db['A'][0] = A
db['Iy'][0] = Iy
db['Iz'][0] = compute_inertia_z(b, h)
// update
update_div_geo(db, div)
update_section(db, section)
// emit the changes
source.change.emit()
{beam_section.implement_update_div_geoJS()}
{beam_section.implement_update_sectionJS()}
{beam_section.implement_compute_areaJS()}
{beam_section.implement_compute_inertia_yJS()}
{beam_section.implement_compute_inertia_zJS()}
"""
update_h = CustomJS(args=args_slider_b_h, code=code_change_h)
args_checkbox_P = dict(source=source,
s_M=source_M,
div_P=div_cb_P,
div_f=div_forces,
fP=scheme_axial_force,
fRx=scheme_Rx_l,
fRyl=scheme_Ry_l,
fRyr=scheme_Ry_r,
fN=scheme_N,
fV=scheme_V,
arr_head=scheme_M_head,
N_diag=N_diag)
code_checkbox_P = f"""
// retrieve var from the object that uses callback
var f = cb_obj.active // checkbox P
if (f.length==0) f = [1]
const db = source.data
// apply the changes
db['P'][0] = {P}*(1-f)
db['N'][0] = compute_N(db['P'][0])
db['Rx'][0] = compute_Rx(db['P'][0])
// update
update_reactions(db, fRx, fRyl, fRyr)
update_external_forces(db, fP, div_P)
update_N_diagram(db, N_diag)
update_internal_forces(db, fN, fV, arr_head, s_M)
update_div_forces(db, div_f)
// emit the changes
source.change.emit()
// declare functions
{sb.implement_update_external_forcesJS()}
{sb.implement_update_reactionsJS()}
{sb.implement_compute_RxJS()}
{js.implement_update_arrowJS()}
{js.implement_arrow_alphaJS()}
{js.implement_update_NVM_diagramJS()}
{sb.implement_compute_NJS()}
{sb.implement_update_N_diagramJS(discr_NVM)}
{sb.implement_update_internal_forcesJS()}
{js.implement_update_curvedArrowJS()}
{sb.implement_update_div_forcesJS()}
{js.implement_arrow_growthJS()}
"""
update_checkbox_P = CustomJS(args=args_checkbox_P, code=code_checkbox_P)
args_radiogroup_FBD = dict(source=source,
s_sb=source_scheme_beam,
s_q=source_scheme_q,
s_M=source_M,
div_P=div_cb_P,
fP=scheme_axial_force,
fRx=scheme_Rx_l,
fRyl=scheme_Ry_l,
fRyr=scheme_Ry_r,
fN=scheme_N,
fV=scheme_V,
arr_head=scheme_M_head)
code_radiogroup_FBD = f"""
// retrieve data
const db = source.data
const FBD = cb_obj.active
const data_sb = s_sb.data
const data_q = s_q.data
const pos = db['x'][0]
// apply the changes
db['FBD'][0] = FBD
// update
check_state(db)
update_internal_forces(db, fN, fV, arr_head, s_M)
update_scheme_position(db, data_sb, data_q)
update_reactions(db, fRx, fRyl, fRyr)
update_external_forces(db, fP, div_P)
// emit the changes
source.change.emit()
s_sb.change.emit()
s_q.change.emit()
{models.implement_check_stateJS()}
{sb.implement_update_internal_forcesJS()}
{sb.implement_update_scheme_positionJS()}
{js.implement_update_curvedArrowJS()}
{js.implement_update_arrowJS()}
{sb.implement_update_reactionsJS()}
{sb.implement_update_external_forcesJS()}
{js.implement_arrow_alphaJS()}
{js.implement_arrow_growthJS()}
"""
update_radiogroup_FBD = CustomJS(args=args_radiogroup_FBD, code=code_radiogroup_FBD)
args_slider_q = dict(source=source,
s_q=source_scheme_q,
s_M=source_M,
div_f=div_forces,
div_P=div_cb_P,
fP=scheme_axial_force,
fRx=scheme_Rx_l,
fRyl=scheme_Ry_l,
fRyr=scheme_Ry_r,
fN=scheme_N,
fV=scheme_V,
arr_head=scheme_M_head,
V_diag=V_diag,
M_diag=M_diag)
code_slider_q = f"""
// retrieve data
const db = source.data
const q = cb_obj.value
const pos = db['x'][0]
const L = db['L'][0]
// update q
db['q'][0] = q
db['V'][0] = compute_V(pos, q, L)
db['M'][0] = compute_M(pos, q, L)
db['Ry_l'][0] = compute_Ry_l(q, L)
db['Ry_r'][0] = compute_Ry_r(q, L)
// update
update_u_load(db, s_q)
update_reactions(db, fRx, fRyl, fRyr)
update_external_forces(db, fP, div_P)
update_V_diagram(db, V_diag)
update_M_diagram(db, M_diag)
update_internal_forces(db, fN, fV, arr_head, s_M)
update_div_forces(db, div_f)
// apply changes
source.change.emit()
// declare functions
{js.implement_update_arrowJS()}
{js.implement_linspaceJS()}
{js.implement_parabolaJS()}
{js.implement_arrow_alphaJS()}
{js.implement_update_arrowJS()}
{sb.implement_compute_VJS()}
{sb.implement_compute_MJS()}
{sb.implement_compute_Ry_lJS()}
{sb.implement_compute_Ry_rJS()}
{js.implement_update_NVM_diagramJS()}
{sb.implement_update_V_diagramJS(discr_NVM)}
{sb.implement_update_M_diagramJS(discr_NVM)}
{sb.implement_update_reactionsJS()}
{sb.implement_update_external_forcesJS()}
{sb.implement_update_u_loadJS(OFFSET_Q)}
{sb.implement_update_internal_forcesJS()}
{js.implement_update_curvedArrowJS()}
{sb.implement_update_div_forcesJS()}
{js.implement_arrow_growthJS()}
"""
update_slider_q = CustomJS(args=args_slider_q, code=code_slider_q)
# apply the logics
slider_b.js_on_change('value', update_b)
slider_h.js_on_change('value', update_h)
slider_position.js_on_change('value', updade_slider_pos)
checkbox_P.js_on_click(update_checkbox_P)
radiogroup_FBD.js_on_click(update_radiogroup_FBD)
slider_q.js_on_change('value', update_slider_q)
########################################################
# Build the layout
########################################################
padding_layout = 10
layout1 = layout([
[column(row(column(fig_scheme,
row(fig_section, Spacer(width=padding_layout), column(Spacer(height=padding_layout),
slider_b,
slider_h,
div_geo,
Spacer(height=padding_layout),
slider_position,
slider_q,
div_rg_FBD,
radiogroup_FBD,
div_cb_P,
checkbox_P))),
column(fig_beam,
Spacer(height=padding_layout),
fig_N,
fig_V,
fig_M,
div_forces))
)],
])
show(layout1)

Event Timeline