Análisis matricial de armaduras con Python

Capítulo 2

Nuestro primer notebook

Todo análisis de una armadura empieza por su geometría. Antes de hablar de rigideces, cada barra debe quedar descrita por su longitud y por su orientación en el plano. En este capítulo damos el primer paso de nuestra calculadora: obtenemos la geometría de una barra, escribiendo nuestras primeras líneas de Python en un notebook de Google Colab.

No necesitamos instalar nada. Basta con una cuenta de Google y un navegador.

2.1 La geometría de una barra

Consideremos una barra que va de un nodo inicial ii, de coordenadas (xi,yi)(x_i, y_i), a un nodo final jj, de coordenadas (xj,yj)(x_j, y_j) (figura 2.1). Las proyecciones de la barra sobre los ejes son

Δx=xj−xi,Δy=yj−yi,(2.1)\Delta x = x_j - x_i, \qquad \Delta y = y_j - y_i, \tag{2.1}

y con ellas obtenemos su longitud y sus cosenos directores (direction cosines):

L=Δx2+Δy2,c=cos⁡θ=ΔxL,s=sin⁡θ=ΔyL.\begin{aligned} L = \sqrt{\Delta x^2 + \Delta y^2}, \qquad c = \cos\theta = \frac{\Delta x}{L}, \qquad s = \sin\theta = \frac{\Delta y}{L}. \end{aligned}

El ángulo θ\theta se mide desde el eje xx global, en sentido antihorario, hasta la dirección que va del nodo ii al nodo jj. Por eso el orden de los nodos importa: si intercambiamos ii y jj, cambian los signos de cc y ss, y el ángulo aumenta en 180°.

Figura 2.1:

Geometría de una barra: proyecciones, longitud y ángulo.

Estas tres cantidades parecen modestas, pero las usaremos en todo el libro: la longitud interviene en la rigidez de la barra, y los cosenos directores en la matriz de transformación del capítulo 5.

2.2 Nuestro primer notebook

Un notebook es un documento que mezcla celdas de texto y celdas de código que se pueden ejecutar. Usaremos Google Colab (Google Colaboratory), un servicio gratuito que ejecuta notebooks de Python en los servidores de Google. Tiene dos ventajas decisivas para nosotros: no requiere instalar nada, y ya incluye las bibliotecas que usa este libro.

Crear el notebook en Google Drive

Para que nuestro trabajo quede guardado y organizado, creamos el notebook dentro de nuestro propio Google Drive:

  1. Abrir drive.google.com con nuestra cuenta de Google.
  2. Crear una carpeta para el curso, por ejemplo Calculadora de armaduras.
  3. Dentro de la carpeta, elegir Nuevo →\to Más →\to Google Colaboratory. Si la opción no aparece, elegir Conectar más aplicaciones, buscar Colaboratory e instalarla.
  4. Cambiar el nombre del notebook (arriba a la izquierda), por ejemplo, Capitulo 02.

La figura 2.2 muestra el menú para crear el notebook, y la figura 2.3, el notebook recién creado.

Aquí debe ir la captura colab_nuevo.png:
Google Drive con la carpeta del curso abierta y el menú Nuevo, Más, Google Colaboratory desplegado.
Figura 2.2:

Crear un notebook de Colab dentro de nuestra carpeta de Google Drive.

Aquí debe ir la captura colab_vacio.png:
el notebook recién creado en Colab, con su nombre cambiado a Capitulo 02 y una celda de código vacía.
Figura 2.3:

Un notebook nuevo, listo para escribir la primera celda.

Celdas de código

Un notebook nuevo trae una celda de código vacía. Escribimos en ella la siguiente línea y la ejecutamos con el botón de reproducción, a la izquierda de la celda, o con las teclas Mayús + Enter:

print("Hola, armaduras")
Hola, armaduras

La primera ejecución tarda unos segundos, porque Colab prepara una máquina para nosotros. Debajo de la celda aparece lo que el programa imprime (figura 2.4).

Aquí debe ir la captura colab_primera_celda.png:
la primera celda del capítulo ya ejecutada en Colab, con el botón de ejecución a la izquierda y su salida debajo.
Figura 2.4:

La primera celda ejecutada y su resultado.

Una celda también puede contener una operación. Si la última línea de una celda es una expresión, el notebook muestra su valor:

2 + 3 * 4
14

Python respeta la precedencia habitual: la multiplicación se evalúa antes que la suma. Para agregar celdas usamos los botones + Código y + Texto; las celdas de texto sirven para anotar qué estamos calculando.

2.3 Variables y operaciones

Una variable es un nombre que guarda un valor. Guardemos las coordenadas de los nodos de la barra 3 del ejemplo A, que va del nodo 1, en (0,0)(0, 0), al nodo 3, en (3,4)(3, 4):

# Coordenadas (en m) del nodo inicial i y del nodo final j
x_i = 0.0
y_i = 0.0
x_j = 3.0
y_j = 4.0

El signo = no expresa una igualdad matemática: es una asignación (assignment). Se lee «guardar el valor 0.0 con el nombre x_i». Las líneas que empiezan con # son comentarios: Python las ignora, pero a nosotros nos recuerdan qué representa cada valor.

Con las variables definidas, calculamos las proyecciones de la ecuación (2.1). Al escribir dos expresiones separadas por una coma, el notebook muestra ambas:

dx = x_j - x_i
dy = y_j - y_i
dx, dy
(3.0, 4.0)

Las operaciones aritméticas se escriben con +, -, * y /, y la potencia con **. La suma de los cuadrados de las proyecciones es:

dx**2 + dy**2
25.0

Los números muy grandes o muy pequeños se escriben en notación científica (scientific notation): 2.0e8 significa 2.0×1082.0\times10^{8}. Así escribiremos el módulo de elasticidad del acero en kN/m²:

E = 2.0e8  # módulo de elasticidad del acero, en kN/m²
A = 0.0020  # área de la sección, en m²
E * A
400000.0

El producto EA=400 000 kNEA = 400\,000\,\mathrm{kN} es la rigidez axial de la sección; la retomaremos en el capítulo 5.

2.4 El módulo math

Python trae incorporadas solo las operaciones básicas. Las funciones matemáticas, como la raíz cuadrada o las funciones trigonométricas, están en el módulo (module) math, que debemos importar una vez por notebook:

import math

A partir de ese momento, escribimos las funciones del módulo con el prefijo math seguido de un punto. La longitud de la barra es:

L = math.sqrt(dx**2 + dy**2)
L
5.0

Y sus cosenos directores:

c = dx / L
s = dy / L
c, s
(0.6, 0.8)

Para el ángulo usamos math.atan2(dy, dx), que devuelve el ángulo en radianes, y math.degrees, que lo convierte a grados:

theta = math.degrees(math.atan2(dy, dx))
theta
53.13010235415598

2.5 Mostrar resultados con print y f-strings

El ángulo anterior aparece con catorce decimales, una precisión que ninguna medición justifica. Para presentar resultados usamos print junto con f-strings (formatted string literals): textos precedidos por una f en los que cada expresión entre llaves se reemplaza por su valor. Después de los dos puntos indicamos el formato; por ejemplo, :.3f significa «número con tres decimales»:

print(f"Longitud: L = {L:.3f} m")
print(f"Cosenos directores: c = {c:.4f}, s = {s:.4f}")
print(f"Ángulo: θ = {theta:.2f}°")
Longitud: L = 5.000 m
Cosenos directores: c = 0.6000, s = 0.8000
Ángulo: θ = 53.13°

De ahora en adelante, todo resultado que presentemos llevará sus unidades y una cantidad razonable de decimales: milímetros para los desplazamientos, tres cifras significativas para las fuerzas.

2.6 La geometría de una barra en Python

Reunimos todo lo anterior para obtener la geometría completa de una barra. Los pasos son siempre los mismos:

Problema resuelto 2.1 · Barra 2 del ejemplo A

La barra 2 del ejemplo A va del nodo 2, en (6,0)(6, 0), al nodo 3, en (3,4)(3, 4), con coordenadas en metros. Determinar su longitud, sus cosenos directores y su ángulo.

Solución

Las proyecciones son Δx=3−6=−3 m\Delta x = 3 - 6 = -3\,\mathrm{m} y Δy=4−0=4 m\Delta y = 4 - 0 = 4\,\mathrm{m}. En Python:

# Barra 2 del ejemplo A: del nodo 2 al nodo 3
x_i, y_i = 6.0, 0.0
x_j, y_j = 3.0, 4.0

dx = x_j - x_i
dy = y_j - y_i
L = math.sqrt(dx**2 + dy**2)
c = dx / L
s = dy / L
theta = math.degrees(math.atan2(dy, dx))

print(f"L = {L:.3f} m")
print(f"c = {c:.4f}, s = {s:.4f}")
print(f"θ = {theta:.2f}°")
L = 5.000 m
c = -0.6000, s = 0.8000
θ = 126.87°

Verificación. La barra sube hacia la izquierda, de modo que cc debe ser negativo y ss positivo, como obtuvimos. Además, c2+s2=0.36+0.64=1c^2 + s^2 = 0.36 + 0.64 = 1. El ángulo está en el segundo cuadrante, entre 90° y 180°, lo que también coincide con el dibujo.

Repaso y resumen del capítulo

Ejercicios

Los ejercicios con resultado numérico tienen una celda de verificación en el notebook del capítulo: al escribir allí el resultado y ejecutar la celda, se indica si es correcto.

Cada ejercicio tiene su solución completa debajo del enunciado.

Ejercicio 2.1

Calcular la longitud y los cosenos directores de la barra 1 del ejemplo A, que va del nodo 1, en (0,0)(0, 0), al nodo 2, en (6,0)(6, 0). ¿Por qué el resultado podía anticiparse sin calcular?

Ver la solución
# Barra 1 del ejemplo A: de (0, 0) a (6, 0)
dx = 6.0 - 0.0
dy = 0.0 - 0.0
L = math.sqrt(dx**2 + dy**2)
c = dx / L
s = dy / L
print(f"L = {L:.3f} m")
print(f"c = {c:.4f}, s = {s:.4f}")
L = 6.000 m
c = 1.0000, s = 0.0000

La barra es horizontal y apunta en el sentido positivo de xx: su longitud es la diferencia de abscisas, c=1c = 1 y s=0s = 0.

Ejercicio 2.2

Una barra del cordón superior de una armadura de cubierta va de (0,0)(0, 0) a (4.5,1.5)(4.5, 1.5), en metros. Calcular su longitud, sus cosenos directores y su ángulo en grados.

Ver la solución
# Barra de cubierta: de (0, 0) a (4.5, 1.5)
dx = 4.5 - 0.0
dy = 1.5 - 0.0
L = math.sqrt(dx**2 + dy**2)
c = dx / L
s = dy / L
theta = math.degrees(math.atan2(dy, dx))
print(f"L = {L:.3f} m")
print(f"c = {c:.4f}, s = {s:.4f}")
print(f"θ = {theta:.2f}°")
L = 4.743 m
c = 0.9487, s = 0.3162
θ = 18.43°

Ejercicio 2.3

La barra 3 del ejemplo A es de acero (E=200 GPaE = 200\,\mathrm{GPa}), tiene un área de 20 cm² y una longitud de 5 m. Calcular su rigidez axial EA/LEA/L en kN/m. Cuidar la conversión de unidades.

Ver la solución

Con E=200 GPa=2.0×108 kN/m2E = 200\,\mathrm{GPa} = 2.0\times10^{8}\,\mathrm{kN/m^2} y A=20 cm2=0.0020 m2A = 20\,\mathrm{cm^2} = 0.0020\,\mathrm{m^2}:

E = 2.0e8  # kN/m²
A = 0.0020  # m²
L = 5.0  # m
rigidez_axial = E * A / L
print(f"EA/L = {rigidez_axial:.0f} kN/m")
EA/L = 80000 kN/m

Ejercicio 2.4

Una barra va de (6,0)(6, 0) a (0,3)(0, 3). Calcular su ángulo con math.atan(dy / dx) y con math.atan2(dy, dx). Explicar cuál es el correcto y por qué, apoyándose en un dibujo de la barra.

Ver la solución
# Barra de (6, 0) a (0, 3): hacia la izquierda y arriba
dx = 0.0 - 6.0
dy = 3.0 - 0.0
con_atan = math.degrees(math.atan(dy / dx))
con_atan2 = math.degrees(math.atan2(dy, dx))
print(f"Con atan:  θ = {con_atan:.2f}°")
print(f"Con atan2: θ = {con_atan2:.2f}°")
Con atan:  θ = -26.57°
Con atan2: θ = 153.43°

La barra apunta hacia la izquierda y hacia arriba, de modo que su ángulo está en el segundo cuadrante: el correcto es el de math.atan2. El cociente Δy/Δx=3/(−6)\Delta y / \Delta x = 3/(-6) es igual al de una barra que apunta hacia la derecha y hacia abajo, y math.atan no puede distinguir ambos casos.

Ejercicio 2.5

Una barra vertical va de (2,3)(2, 3) a (2,−1)(2, -1). Calcular su longitud, sus cosenos directores y su ángulo. ¿Qué ocurre si se intenta calcular el ángulo con math.atan(dy / dx)?

Ver la solución
# Barra vertical: de (2, 3) a (2, -1)
dx = 2.0 - 2.0
dy = -1.0 - 3.0
L = math.sqrt(dx**2 + dy**2)
c = dx / L
s = dy / L
theta = math.degrees(math.atan2(dy, dx))
print(f"L = {L:.3f} m")
print(f"c = {c:.4f}, s = {s:.4f}")
print(f"θ = {theta:.2f}°")
L = 4.000 m
c = 0.0000, s = -1.0000
θ = -90.00°

Si se usa math.atan(dy / dx), la división por Δx=0\Delta x = 0 produce el error ZeroDivisionError y el programa se detiene.