Construir y calcular un modelo en Python
Siete objetos cubren casi cualquier modelo: Node, Material, Section, Member, MemberSet, NodalSupport y NodalLoad. Los ensambla, llama a run_analysis() y lee un conjunto de resultados indexado por hipótesis de carga.
Los objetos principales
Todo se importa desde fers_core. Un modelo es una instancia de FERS que contiene grupos de barras; las cargas cuelgan de las hipótesis y no del modelo, de modo que la misma geometría puede soportar varias hipótesis independientes.
- Node — un punto X, Y, Z. Y es la vertical hacia arriba. Los nudos llevan su condición de apoyo.
- Material — módulo de elasticidad, módulo de cortante, densidad y límite elástico. Todo en SI: pascales y kg/m³.
- Section — área y momentos de inercia, referidos a un material.
- Member — un elemento viga de dos nudos con seis grados de libertad por nudo, referido a una sección.
- MemberSet — el grupo que añade al modelo y también la unidad sobre la que actúan las comprobaciones.
- NodalSupport — la condición de contorno asignada a un nudo.
- NodalLoad — una fuerza o un momento aplicado a un nudo dentro de una hipótesis de carga.
from fers_core import (
FERS, Node, Member, Section, Material,
MemberSet, NodalSupport, NodalLoad
)Definir geometría, material y sección
Las coordenadas van en metros y las propiedades del material en pascales. La sección de abajo es un IPE 180 tomado de la biblioteca de perfiles de FERS.
Fíjese en el convenio de ejes, porque es con diferencia la causa más habitual de un resultado erróneo: i_z es el eje fuerte e i_y el débil. Una viga que flecta en su plano habitual se gobierna por i_z.
# Nodes (x, y, z coordinates in metres)
node1 = Node(0, 0, 0)
node2 = Node(5, 0, 0)
# Material (Steel S235)
steel = Material(
name="Steel S235",
e_mod=210e9, # Pa
g_mod=80.769e9, # Pa
density=7850, # kg/m³
yield_stress=235e6 # Pa
)
# Cross-section (IPE 180), values from the FERS steel section library.
# Axis convention: i_z is the STRONG axis (bending in the local x-y plane),
# i_y the weak axis — see ferscloud.com/conventions
section = Section(
name="IPE 180",
material=steel,
i_y=1.009e-6, # m⁴ (weak axis)
i_z=13.17e-6, # m⁴ (strong axis)
j=0.0477e-6, # m⁴
area=0.00240 # m²
)Todos los convenios de ejes, signos y unidades están en la página de convenios. El contrato JSON espera ángulos en grados, no en radianes.
Crear la barra, aplicar apoyo y carga
Un NodalSupport() sin argumentos está totalmente empotrado. Para una articulación o un apoyo deslizante, pase displacement_conditions y rotation_conditions explícitos — los ejemplos muestran ambos casos.
Las direcciones de carga son vectores unitarios globales, así que (0, 1, 0) con módulo negativo es una fuerza hacia abajo.
# Create beam element
beam = Member(start_node=node1, end_node=node2, section=section)
# Fixed support at node1
node1.nodal_support = NodalSupport()
# Organise members into a set and add to model
model = FERS()
model.add_member_set(MemberSet(members=[beam]))
# Load case with a −1 kN point load at node2
lc = model.create_load_case(name="Gravity")
NodalLoad(node=node2, load_case=lc, magnitude=-1000, direction=(0, 1, 0))Lanzar el cálculo y leer resultados
run_analysis() resuelve todas las hipótesis. Los resultados quedan en model.resultsbundle, indexados por nombre de hipótesis, con desplazamientos y reacciones indexados por identificador de nudo como cadena.
Los comentarios muestran la salida real para estas entradas exactas.
model.run_analysis()
results = model.resultsbundle.loadcases["Gravity"]
dy = results.displacement_nodes["2"].dy
Vy = results.reaction_nodes["1"].nodal_forces.fy
Mz = results.reaction_nodes["1"].nodal_forces.mz
print(f"Tip deflection : {dy*1000:.3f} mm") # -15.065 mm
print(f"Reaction Vy : {Vy:.1f} N") # 1000.0 N
print(f"Reaction Mz : {Mz:.1f} Nm") # 5000.0 NmComprobación manual: una ménsula de 5 m que flecta respecto a su eje fuerte da δ = PL³ / 3EI_z = 1000·5³ / (3 · 210×10⁹ · 13,17×10⁻⁶) = 15,07 mm, con una reacción de 1 kN y un momento de empotramiento de 5 kN·m por equilibrio. El solver devuelve 15,065 mm.
Más allá de la estática lineal
El mismo objeto de modelo lleva la configuración de los demás tipos de análisis. El análisis de segundo orden (P-Delta), el pandeo lineal con factor de carga crítica, el análisis modal y el sísmico por espectro de respuesta se gobiernan desde los ajustes de análisis, no desde una API distinta.
Las comprobaciones se asocian a grupos de barras y se evalúan tras el cálculo, devolviendo aprovechamientos cláusula a cláusula junto con los valores intermedios que los produjeron: una comprobación se lee como un cálculo manual y no como un número suelto.
- Contraste primero con soluciones cerradas — véanse los contrastes de precisión y el conjunto NAFEMS.
- Para comprobaciones según EN 1993-1-1,
check_beamconstruye, calcula y comprueba un vano en una sola llamada — véanse los ejemplos.
Páginas relacionadas
Instalar el paquete Python de FERS
Instalar con pip, verificar la importación y configurar opcionalmente la autenticación en la nube con clave de API o token.
Ejemplos resueltos
Cuatro scripts ejecutables — ménsula, viga biapoyada, pórtico y comprobación según EN 1993-1-1 — cada uno con su cálculo manual.
Véase también
Preguntas frecuentes
¿Por qué mis desplazamientos están indexados por una cadena?
displacement_nodes["2"], no [2].¿Para qué sirve un MemberSet?
¿Cómo modelo una articulación o un apoyo deslizante?
NodalSupport. Una articulación fija las tres traslaciones y deja libres los giros de flexión; retenga además el giro de torsión o la barra tendrá un modo de sólido rígido y el sistema será singular. El ejemplo de viga biapoyada muestra ambos.¿Qué momento de inercia corresponde al eje fuerte?
i_z. FERS trata el eje z local como eje fuerte de flexión en todo el sistema: solver, comprobaciones y diagramas coinciden. Intercambiar i_y e i_z es el error de modelado más común.¿Necesito conexión a Internet para calcular?
run_analysis() ejecuta el solver compilado dentro de su propio proceso. Solo se usa la red si llama a un punto final en la nube.