IA en la Ingeniería Estructural

Recientemente, tuve la oportunidad de explorar las capacidades de Claude, una IA recomendada por su eficacia en la generación de código. La experiencia fue verdaderamente impresionante y reveladora.
Con solo un par de prompts bien formulados, logré obtener un código completo y funcional para calcular la respuesta estructural de un sistema de un grado de libertad (SDOF) elasto-plástico sometido a un registro sísmico aleatorio. Este proceso, que tradicionalmente requeriría una considerable inversión de tiempo en programación y depuración, se completó en cuestión de minutos.
Aspectos destacados de la experiencia:

  1. Rapidez: La generación de código fue casi instantánea.
  2. Precisión: El código producido se ejecuto sin errores.
  3. Complejidad: La IA manejó con soltura conceptos avanzados de dinámica estructural.
  4. Personalización: Fue capaz de adaptar el código según mis requerimientos específicos.

Esta experiencia me ha llevado a reflexionar sobre el futuro de nuestra profesión. El empleo de la IA en la ingeniería estructural, al igual que en otros campos, está destinado a convertirse en una herramienta indispensable. No se trata de reemplazar al ingeniero, sino de potenciar nuestras capacidades.

import numpy as np
import matplotlib.pyplot as plt

def generate_random_ground_motion(duration, dt):
    t = np.arange(0, duration, dt)
    n = len(t)

    num_components = 10
    frequencies = np.random.uniform(0.1, 5, num_components)
    amplitudes = np.random.uniform(0.1, 1, num_components)
    phases = np.random.uniform(0, 2*np.pi, num_components)

    ag = np.zeros(n)
    for f, a, p in zip(frequencies, amplitudes, phases):
        ag += a * np.sin(2 * np.pi * f * t + p)

    ag += np.random.normal(0, 0.1, n)
    ag *= 0.1

    return t, ag

def perfect_plastic_sdof_newmark(m, k, fy, dt, ag, gamma=0.5, beta=0.25):
    omega = np.sqrt(k / m)
    T = 2 * np.pi / omega
    c = 2 * m * omega * 0.05  # 5% damping

    n = len(ag)
    x = np.zeros(n)
    v = np.zeros(n)
    a = np.zeros(n)
    fs = np.zeros(n)

    # Initial conditions
    x[0] = 0
    v[0] = 0
    a[0] = (fy - c * v[0] - k * x[0] - m * ag[0]) / m

    for i in range(1, n):
        # Predict
        x_pred = x[i-1] + dt * v[i-1] + 0.5 * dt**2 * ((1 - 2*beta) * a[i-1])
        v_pred = v[i-1] + dt * ((1 - gamma) * a[i-1])

        # Calculate restoring force
        if abs(k * x_pred) < fy:
            fs[i] = k * x_pred
        else:
            fs[i] = np.sign(x_pred) * fy

        # Solve for acceleration
        a[i] = (fs[i] - c * v_pred - k * x_pred - m * ag[i]) / m

        # Correct
        x[i] = x_pred + beta * dt**2 * a[i]
        v[i] = v_pred + gamma * dt * a[i]

        # Update restoring force
        if abs(k * x[i]) < fy:
            fs[i] = k * x[i]
        else:
            fs[i] = np.sign(x[i]) * fy

    return x, v, a, fs, T

# Set random seed for reproducibility
np.random.seed(42)

# Generate random ground motion
duration = 30  # seconds
dt = 0.01  # time step
t, ag = generate_random_ground_motion(duration, dt)

# SDOF system parameters
m = 1.0  # mass
T = 0.5  # natural period
omega = 2 * np.pi / T
k = m * omega**2  # stiffness
fy = 0.1 * m * 9.81  # yield force (10% of weight)

# Calculate SDOF response using Newmark method
x, v, a, fs, T = perfect_plastic_sdof_newmark(m, k, fy, dt, ag)

# Plot results
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, figsize=(10, 16), sharex=True)

ax1.plot(t, ag)
ax1.set_ylabel('Ground Acceleration (g)')
ax1.set_title('Random Ground Motion and SDOF Perfect Plastic Response (Newmark Method)')
ax1.grid(True)

ax2.plot(t, x)
ax2.set_ylabel('Displacement (m)')
ax2.grid(True)

ax3.plot(t, v)
ax3.set_ylabel('Velocity (m/s)')
ax3.grid(True)

ax4.plot(t, fs)
ax4.set_xlabel('Time (s)')
ax4.set_ylabel('Restoring Force (N)')
ax4.grid(True)

plt.tight_layout()
plt.show()

# Plot force-displacement relationship
plt.figure(figsize=(8, 6))
plt.plot(x, fs)
plt.xlabel('Displacement (m)')
plt.ylabel('Restoring Force (N)')
plt.title('Force-Displacement Relationship (Newmark Method)')
plt.grid(True)
plt.show()

# Print some response statistics
print(f"Maximum displacement: {np.max(np.abs(x)):.4f} m")
print(f"Maximum velocity: {np.max(np.abs(v)):.4f} m/s")
print(f"Maximum acceleration: {np.max(np.abs(a)):.4f} m/s^2")
print(f"Maximum restoring force: {np.max(np.abs(fs)):.4f} N")

Deja una respuesta