femppp es un código educativo de Elementos Finitos (FEM) desarrollado en Python para la enseñanza de la mecánica de sólidos en régimen de esfuerzo plano. El código está diseñado para ser ejecutado en Jupyter Lab y hace uso intensivo de numpy y scipy.sparse para un ensamblaje eficiente.
En problemas de esfuerzo plano se asume que no hay fuerzas en la dirección
Las deformaciones asociadas son:
con las relaciones cinemáticas lineales:
La relación constitutiva
donde
El método de elementos finitos implementado se basa en la formulación débil derivada del principio de mínima energía potencial total. Para un sólido elástico lineal, la energía potencial total
donde:
-
$\Lambda$ es la energía de deformación interna, -
$W_{\text{ext}}$ es el trabajo realizado por las fuerzas externas, -
$\mathbf{U}$ es el vector de desplazamientos nodales (incógnitas).
La condición de equilibrio corresponde al punto estacionario de
El dominio se discretiza mediante triángulos de tres nodos. En cada elemento los desplazamientos se interpolan linealmente a partir de los valores nodales usando funciones de forma
Las funciones de forma en coordenadas cartesianas son:
donde
Estas funciones satisfacen
Las deformaciones se obtienen derivando el campo de desplazamientos, resultando en una matriz constante para cada elemento:
La energía de deformación se expresa como:
Dado que
siendo
Para una fuerza por unidad de volumen
Se aplican directamente en los grados de libertad correspondientes mediante el método apply_point_loads.
Para una carga superficial
(análogamente para las otras aristas). Esta expresión corresponde a una distribución lineal de las fuerzas nodales equivalentes.
El proceso de ensamblaje sigue los pasos clásicos:
- Se calculan las matrices elementales
$[K]^{(e)}$ y los vectores de carga. - Se determina la correspondencia entre grados de libertad locales y globales.
- Se ensambla la matriz global
$[K]$ en formato sparse (lil_matrixinicialmente, luego convertida acsr_matrixpara eficiencia). - Se aplican condiciones de borde Dirichlet (desplazamientos prescritos) mediante eliminación o partición del sistema.
- Se resuelve el sistema lineal
$[K_{ff}]{u_f} = {f_f}$ usando un solver directo (spsolve) o iterativo (cg,gmres,bicgstab).
Para mejorar el rendimiento, el ensamblaje de la matriz de rigidez se realiza de forma vectorizada: se recolectan todas las matrices coo_matrix con todas las contribuciones.
El repositorio incluye ejemplos que reproducen benchmarks clásicos de la literatura:
- Viga en voladizo con carga puntual en el extremo: comparación con la solución analítica de Euler-Bernoulli.
- Viga bi‑empotrada con carga de gravedad (propuesta por el usuario).
- Viga trapezoidal del benchmark NAFEMS (caso de gravedad), validando los valores de esfuerzo cortante y normal en puntos específicos.
Estos ejemplos están documentados en notebooks de Jupyter y permiten visualizar la convergencia de la solución al refinar la malla.
-
FEMProblem: clase principal que gestiona el ensamblaje, las condiciones de borde y la solución. -
TriangularElement: clase que define el elemento CST (geometría, matriz$[B]$ , matriz de rigidez). -
Tessellation: clase auxiliar para generar mallas estructuradas a partir de una nube de puntos (basada enDelaunay). - Módulos de utilidad: funciones para aplicar cargas distribuidas, de cuerpo, etc.
- Zienkiewicz, O. C., Taylor, R. L., & Zhu, J. Z. (2013). The Finite Element Method: Its Basis and Fundamentals. Butterworth-Heinemann.
- Reddy, J. N. (2006). An Introduction to the Finite Element Method. McGraw-Hill.
- NAFEMS (1987). Linear Statics Benchmarks Vol. 1 (caso de viga trapezoidal).