widget 4: o que é um concentrador de tensão?

#HIDDEN
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from ipywidgets import interactive, widgets
from mpl_toolkits.axisartist import SubplotZero
from matplotlib.patches import Ellipse, Rectangle
import numpy.ma as ma
from matplotlib.ticker import FormatStrFormatter
from IPython.display import display, clear_output
import warnings

warnings.filterwarnings("ignore")


#HIDDEN

def circle(C, R):
    t=np.linspace(0,2*np.pi, 200)
    return C+R*np.exp(1j*t)
def Juc(z, lam):#Joukowski transformation
    return z+(lam**2)/z

def deg2radians(deg):
    return deg*np.pi/180

def compute_lines(rho):
    '''
    Based on the Joukowski transformation of the potential flow past a cylinder.
    For reference:
    https://people.eng.unimelb.edu.au/asho/PotentialFlow/notes.pdf
    https://github.com/luca6331/joukowskiAirfoilVisualization/blob/master/Report.pdf
    https://nbviewer.jupyter.org/github/empet/Math/blob/master/Joukowski-airfoil.ipynb
    
    '''

    V_inf = 1
    R = 1
    lam = (R**2 + R*rho/2 - R*(8*R*rho + rho**2)**0.5/2)**0.5
    alpha=deg2radians(0) # angle of attack
    beta=deg2radians(0)  # -beta is the argument of the complex no (Joukovski parameter - circle center)
    center_c= 0 # Center of the circle
    x=np.arange(-3.5, 3.5, 0.1)
    y=np.arange(-5, 5, 0.1)
    x,y=np.meshgrid(x,y)
    z=x+1j*y
    z=ma.masked_where(np.absolute(z-center_c)<=R, z)
    Z=z-center_c
    Z = -1j*Z
    Gamma=-4*np.pi*V_inf*R*np.sin(beta+alpha)
    U=np.zeros(Z.shape)
    with np.errstate(all='ignore'):#avoid warning when evaluates np.log(0+1jy).
                                         #In this case the arg is arctan(y/0)+cst
            for m in range(Z.shape[0]):
                for n in range(Z.shape[1]):
                    #U[m,n]=Gamma*np.log(Z[m,n]/R)/(2*np.pi)# 
                     U[m,n]=Gamma*np.log((Z[m,n]*np.exp(-1j*alpha))/R)/(2*np.pi)
    c_flow= V_inf*Z*np.exp(-1j*alpha) + (V_inf*np.exp(1j*alpha)*R**2)/Z - 1j*U #the complex flow
    J=Juc(z, lam)
    Circle=circle(0, R)
    Airfoil=Juc(Circle, lam)# airfoil 
    return J, c_flow.imag, Airfoil, rho


def get_zone(point, zones):
    for i, zone in enumerate(zones):
        if zone.get_paths()[0].contains_point(point):
            return i, zone

def html_ticks(ticks, id, ticks_pos=None):
    html_str = f'''
                <style>
                .ruler{id} {{
                 position: relative;
                 width: 100%;
                 margin-top: 20px;
                 height: 0px;
                }}
                .ruler{id} .cm{id},
                .ruler{id} .mm{id} {{
                 position: absolute;
                 border-left: 1px solid #555;
                 height: 0px;
                }}
                .ruler{id} .cm{id}:after {{
                 position: absolute;
                 bottom: -15px;
                 font: 11px/1 sans-serif;
                }}
                .ruler{id} .cm{id}:nth-of-type(1) {{
                 left: 0%;
                }}
                .ruler{id} .cm{id}:nth-of-type(1):after {{
                 content: "0.01";
                }}
                '''
    for i, tick in enumerate(ticks[1:]):
        if not ticks_pos:
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}) {{left: {(i+1) * 100 / (len(ticks) - 1)}%;}}'
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}):after {{content: "{ticks[i+1]}";}}'
        else:
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}) {{left: {ticks_pos[i+1]}%;}}'
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}):after {{content: "{ticks[i+1]}";}}'

    html_str += '\n</style>'

    html_str += f"\n<div class='ruler{id}'>"
    for i in range(len(ticks)):
        html_str += f"\n<div class='cm{id}'></div>"

    end_str = '</div>'
    html_str += end_str
    return html_str
#HIDDEN

np.seterr(all='ignore')
def f(rho, defect, show_lines):
    fig, ax = plt.subplots(figsize=(6, 6))
    r = Rectangle([-3.5, -4.75], 6.95, 9.5, facecolor='none', edgecolor='k', zorder=10)
    if not defect:
        if not show_lines:
            ax.add_patch(r)

            
        if show_lines:
            xcoords = np.linspace(-3.5, 3.5, 50)
            ax.add_patch(r)
            for xc in xcoords:
                perf = plt.axvline(x=xc, c='blue', lw=1)
                perf.set_clip_path(r)
    if defect: 
        if not show_lines:
            R = 1
            lam = (R**2 + R*rho/2 - R*(8*R*rho + rho**2)**0.5/2)**0.5
            c = 1
            b = c*rho**0.5
            Circle=circle(0, R)
            Airfoil=Juc(Circle, lam)
            ax.plot(Airfoil.real, Airfoil.imag, c='k')
            ax.add_patch(r)

        if show_lines:
            J, stream_func, Airfoil, rho = compute_lines(rho)
            cp=ax.contour(J.real, J.imag, stream_func,levels=100, colors='blue', linewidths=1,
                            linestyles='solid')# this means that the flow is evaluated at Juc(z) since c_flow(Z)=C_flow(csi(Z))
            ax.add_patch(r)

            for col in cp.collections:
                col.set_clip_path(r)
            ax.plot(Airfoil.real, Airfoil.imag, c='k')
            ax.set_xlim(-5.5, 5.5)
            ax.set_ylim(-5.5, 5.5)
        
    plt.annotate('', xy = (0, 4.725), \
        xytext = (0, 5.5), fontsize = 20, \
        color = '#303030', arrowprops=dict(edgecolor='black', arrowstyle = '<-'))
    plt.text(0.25, 5.25, r'$\sigma_{app}$', fontsize=14)
        
    plt.annotate('', xy = (0, -4.725), \
        xytext = (0, -5.5), fontsize = 20, \
        color = '#303030', arrowprops=dict(edgecolor='black', arrowstyle = '<-'))
    plt.text(0.25, -5.5, r'$\sigma_{app}$', fontsize=14)

    ax.axis('off')
    ax.set_xlim(-5.5, 5.5)
    ax.set_ylim(-5.5, 5.5)
    fig.patch.set_facecolor((1.0, 0.0, 0.0, 0.0))
    plt.show()


rho_slider_base = widgets.FloatSlider(value=0.01,
                                      min=0.01,
                                      max=1,
                                      step=0.01,
                                      description=r'Raio de\nCurvatura do Defeito, 𝜌',
                                      readout=False,
                                      readout_format='.2f',
                                      style= {'description_width': '0px'})
show_lines_button = widgets.ToggleButton(False, description='Linhas de Força')
defect_button = widgets.ToggleButton(True, description='Adicionar o Defeito')

interactive_plot = interactive(f, show_lines=show_lines_button,
                               rho=rho_slider_base,
                               defect=defect_button)

rho_slider_title = widgets.HTMLMath(value=r'Raio de Curvatura do Defeito, 𝜌:')
rho_slider_display = widgets.HTMLMath(value=str(rho_slider_base.value))

rho_slider =  widgets.VBox([rho_slider_title,
                            rho_slider_base,
                            rho_slider_display])
rho_slider.layout = widgets.Layout(align_items='center', width='100%')
def rho_slider_callback(rho_sli):
    rho_slider_display.value =  r"Raio de Curvatura do Defeito, 𝜌 = " + f'{rho_sli:.2f}'

rho_slider_ticks_HTML_str = html_ticks([0.01, 1], 'x')
rho_slider_ticks = widgets.HTML(rho_slider_ticks_HTML_str)
rho_slider_ticks.layout = widgets.Layout(width='290px', margin='0 0 -45px 0px',
                                     pad='0 0 0 0', position='absolute')

rho_slider_ticked = widgets.VBox([rho_slider_ticks, rho_slider])
# rho_slider_ticked.layout = widgets.Layout(height='100%', position='absolute')


widgets.interactive_output(
    rho_slider_callback, 
    {"rho_sli": rho_slider_base})

output = interactive_plot.children[-1]
# output.layout.height = '660px'


output = widgets.VBox([interactive_plot.children[-1],
                       show_lines_button,
                       defect_button,
                       rho_slider_ticked])

output.layout = widgets.Layout(display='flex',
                               flex_flow='column',
                               align_items='center',
                               align_content='center',
                               justify_content='center',
                               width='100%',
                               height='650px',
                               overflow='hidden')
interactive_plot.update()
output
 

metadados

comentários: