Código

Tu primer modelo elástico en OpenSeesPy

Detecta la instalación de OpenSeesPy en tu máquina, construye un voladizo elástico 2D y compara el desplazamiento en la punta con la forma cerrada de Euler–Bernoulli. Este sitio no empaqueta OpenSees.

Un modelo elástico es la primera comprobación honesta de que tu solver, tus unidades y tu conectividad describen el problema que crees que describen. Este tutorial construye un voladizo prismático 2D en OpenSeesPy y compara el desplazamiento en la punta con la forma cerrada elemental. Es una comprobación estática lineal, no una verificación de norma ni un análisis dinámico.

Detecta primero: tu instalación, no un solver empaquetado

OpenSees se desarrolla en la University of California, Berkeley / PEER. OpenSeesPy es una interfaz Python de ese motor. Lo instalas en el intérprete que ya usas para scripts de ingeniería. Este sitio no envía OpenSees, no redistribuye binarios y no envuelve un solver empaquetado de Mamut. Si un asistente o una página de producto implica lo contrario, trátalo como un error.

Confirma el import antes de construir un modelo:

def require_openseespy():
    try:
        import openseespy.opensees as ops
    except ImportError as exc:
        raise SystemExit(
            "OpenSeesPy is not importable in this interpreter. "
            "Install it yourself, for example `pip install openseespy`, "
            "in the same environment you use for engineering work. "
            "This tutorial does not bundle or redistribute OpenSees."
        ) from exc
    return ops


ops = require_openseespy()

Si esa llamada termina el proceso, para. No pegues un modelo Tcl en una sesión Python, y no asumas que una segunda máquina (CI, el portátil de un colega, un contenedor) tiene la misma rueda. Las notas oficiales de la API están en la documentación de OpenSeesPy. Instalación y salvedades de plataforma cambian; confía en la documentación de tu versión, no en un comando copiado de un blog viejo.

OpenSees en Tcl es un binario aparte. Este artículo usa solo OpenSeesPy.

Requisitos previos

  • Python 3 en tu máquina
  • OpenSeesPy importable en ese intérprete (el paso de detección de arriba)
  • Soltura con los grados de libertad de una viga 2D (axial, transversal, rotación)
  • Un sistema de unidades que no mezclarás (véase el tutorial de unidades enlazado abajo)

El problema de ingeniería

Un voladizo prismático horizontal, longitud L, rigidez a flexión EI, empotrado en x = 0, carga en la punta P en la dirección y negativa. Bajo la teoría de vigas de Euler–Bernoulli (pequeña deflexión, sin deformación por cortante, material elástico lineal), la magnitud del desplazamiento transversal en la punta es:

δ = P L³ / (3 E I)

Esa forma cerrada es el resultado estándar en resistencia de materiales elemental —por ejemplo Timoshenko y Gere, Mechanics of Materials—, no una cláusula copiada de una norma de edificación. La usamos como comprobación independiente, no como sustituto de una norma.

OpenSees es adimensional. Elige un conjunto coherente y quédate en él. Este script usa newtons y metros (P en N, E en Pa, I en m⁴, L en m, desplazamiento en m). Mezclar milímetros en I y dejar L en metros es una forma habitual de obtener un modelo «resuelto» que está mal por muchos órdenes de magnitud.

Implementación

Un elasticBeamColumn con transformación geométrica lineal e interpolación cúbica hermitiana recupera el voladizo de Euler–Bernoulli exactamente para un miembro prismático con cargas solo en los extremos (dentro del ruido de punto flotante). Ese es el punto del primer modelo: si esto discrepa de P L³ / (3 E I), el error está en unidades, condiciones de contorno, dirección de la carga o la firma del elemento — no en «refinar la malla».

ops = require_openseespy()

L = 4.0           # m
E = 2.0e11        # Pa (N/m²)
I = 8.333e-6      # m⁴  (100 mm × 100 mm rectangle: b h³ / 12)
A = 0.01          # m²  (needed by the element; does not affect this tip load)
P = 1000.0        # N, downward

ops.wipe()
ops.model("basic", "-ndm", 2, "-ndf", 3)

ops.node(1, 0.0, 0.0)
ops.node(2, L, 0.0)
ops.fix(1, 1, 1, 1)

ops.geomTransf("Linear", 1)
ops.element("elasticBeamColumn", 1, 1, 2, A, E, I, 1)

ops.timeSeries("Linear", 1)
ops.pattern("Plain", 1, 1)
ops.load(2, 0.0, -P, 0.0)

ops.constraints("Plain")
ops.numberer("RCM")
ops.system("BandGeneral")
ops.algorithm("Linear")
ops.integrator("LoadControl", 1.0)
ops.analysis("Static")
ok = ops.analyze(1)
if ok != 0:
    raise RuntimeError(f"static analysis failed, analyze() returned {ok}")

uy = ops.nodeDisp(2, 2)
delta_closed = P * L**3 / (3.0 * E * I)
rel = abs(abs(uy) - delta_closed) / delta_closed

print(f"OpenSees uy = {uy:.6e} m")
print(f"Closed form = {delta_closed:.6e} m")
print(f"Relative error on |uy| = {rel:.3e}")

Lee la lista de argumentos de elasticBeamColumn de tu build de OpenSeesPy. En 2D el orden habitual es tag, nodos, A, E, Iz, tag de transformación. Una firma 3D inserta G, J, Iy y no coincidirá con este script.

Validación

Trata la forma cerrada como el árbitro de este problema concreto:

  1. |uy| debería coincidir con P L³ / (3 E I) en torno a 1e-8 relativo o mejor en un build típico de doble precisión. Si ves 1e-3 o peor, no «aceptes tolerancia de ingeniería» — encuentra el error de unidades o de GDL.
  2. uy debería ser negativo con la carga de arriba. Un desplazamiento positivo en la punta con Py negativo significa que la carga o el GDL de desplazamiento no es lo que crees.
  3. Parte el miembro en varios segmentos elasticBeamColumn con nodos intermedios. Los cúbicos de Euler–Bernoulli cargados en los extremos deberían quedarse en la forma cerrada; un salto grande después de mallar suele significar un error de transformación, liberación o restricción, no «hacen falta más elementos».
  4. Gira el voladizo a vertical y cárgalo axialmente: el desplazamiento transversal en la punta debe colapsar a cero numérico. Si no, la transformación geométrica o los ejes locales están mal.

Un modelo de lenguaje que imprime un desplazamiento sin esta comprobación no es un solver. Conserva la forma cerrada en el mismo script que llama a OpenSees.

Errores habituales

  • El import funcionó en otro Python. Editores, notebooks y CI a menudo no comparten el intérprete donde corriste pip install.
  • Unidades. E en MPa con I en mm⁴ y L en m es el fallo silencioso clásico. OpenSees igual «convergerá».
  • Máscara fix incorrecta. Dejar la rotación libre en el apoyo no es un voladizo.
  • Elemento 3D en un modelo 2D (o al revés). El análisis puede fallar o, peor, correr con una lista de argumentos mal interpretada.
  • geomTransf omitida o reutilizada con la dimensión equivocada. El Linear 2D no es el Linear 3D que necesita un vector que defina el plano xz local.
  • Confiar en masa por defecto o geomTransf('PDelta') en una primera comprobación elástica. Empieza con Linear y sin masa.

Limitaciones

  • Euler–Bernoulli: sin deformación por cortante. Una viga profunda necesita un elemento tipo Timoshenko y otra forma cerrada.
  • Geometría lineal: esto no es una comprobación P-delta ni de grandes desplazamientos.
  • Prismático, elástico, isótropo, carga solo en el extremo. Carga distribuida, secciones afinadas y uniones semirrígidas son otros modelos.
  • Un caso de carga, estático. Periodos naturales, espectros de respuesta y combinación modal quedan fuera de este artículo. Para dinámica, usa una referencia de dinámica estructural como Chopra, Dynamics of Structures — la entrada de libros de este hub usa el content id chopra-dynamics-of-structures — y sigue manteniendo una comprobación en forma cerrada o de espectro a mano.
  • Las ruedas de OpenSeesPy y los builds Tcl difieren por plataforma. Un resultado que no puedes regenerar en una segunda máquina no es un resultado que debas firmar.
  • Nada de esto sustituye la norma de edificación, el ingeniero responsable con licencia ni un plan documentado de verificación.

Contexto profesional

Un primer modelo elástico es un paso de verificación: ¿esta instalación, este sistema de unidades y esta conectividad reproducen un problema cuya respuesta ya conoces? Los modelos de producción necesitan ese hábito más una revisión independiente. No pegues este voladizo en un archivo de proyecto y llames a la estructura «comprobada».

Referencias

  • Documentación de OpenSees / OpenSeesPy, University of California, Berkeley / PEER. https://openseespydoc.readthedocs.io/
  • McKenna, F. OpenSees: a framework for earthquake engineering simulation. Computing in Science & Engineering, 2011 (contexto del marco; no sustituye la versión que instalaste).
  • Timoshenko, S. P., y Gere, J. M. Mechanics of Materials. Resultado elemental del voladizo δ = P L³ / (3 E I). Cita la edición de tu estante; no copies extractos largos.
  • Chopra, A. K. Dynamics of Structures. Para el paso después de la verificación elástica estática (content id chopra-dynamics-of-structures).