Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Universidad de los Andes
Proyecto de Grado
Desarrollo de algoritmoscomputacionales para la simulacion de
fluidos mediante el metodo de elementosespectrales
Autor:
Hayden Liu Weng
Asesor:
Andres Gonzalez Mancera,
Ph. D.
Proyecto de grado presentado para obtener
el tıtulo de Ingeniero Mecanico en el
Departamento de Ingenierıa Mecanica
Diciembre 2014
Declaracion de propiedad
Yo, Hayden Liu Weng, declaro que este proyecto de grado, titulado ’Desarrollo de algo-
ritmos computacionales para la simulacion de fluidos mediante el metodo de elementos
espectrales’, y el trabajo presentado en el mismo son mıos. Ademas confirmo que:
� En caso de haber consultado el trabajo de otras personas, este sera referenciado
adecuadamente.
� Se hara una mencion agradeciendo a todas las personas que colaboraron en este
proyecto.
� En caso que parte del trabajo haya sido desarrollada en conjunto con otras per-
sonas, se presentara cual fue el aporte de esas personas.
Firma:
Fecha:
i
17/12/2014
”El lenguaje de la experiencia es mas autorizado que cualquier otro razonamiento: los
hechos pueden destruir nuestros raciocinios pero no viceversa.”
Alessandro Volta
UNIVERSIDAD DE LOS ANDES
Resumen
Facultad de ingenierıa
Departamento de Ingenierıa Mecanica
Ingeniero Mecanico
Desarrollo de algoritmos computacionales para la simulacion de fluidos
mediante el metodo de elementos espectrales
por Hayden Liu Weng
Al momento de trabajar con ecuaciones diferenciales no lineales como la de Navier-Stokes
usualmente no es posible obtener una solucion analıtica para el campo de velocidades del
sistema subyacente. Por este motivo, tradicionalmente se ha usado una amplia gama de
metodos computacionales para obtener soluciones aproximadas. Sin embargo, muchas
veces el algoritmo de solucion tentativo no es aplicable debido a la falta de informacion,
a las geometrıas complejas o simplemente porque su ejecucion resulta bastante lenta.
Es por esto que, a medida que aumenta la capacidad de computo de los ordenadores,
ası mismo lo hacen las exigencias de los algoritmos de solucion y la complejidad de los
problemas a resolver.
Particularmente, son de especial interes las familias de metodos espectrales y de ele-
mentos finitos. Por un lado, la primer familia presenta soluciones bastante rapidas (con
convergencia espectral – o mas rapida que cualquier potencia de 1/N), pero que solo son
aplicables a geometrıas sencillas. Por otro lado, la segunda familia permite la solucion
de sistemas con geometrıas esencialmente arbitrarias, a costa de un tiempo mayor de
ejecucion. Tratando de combinar ambas familias de metodos para poder trabajar con
tasas de convergencia altas en geometrıas mas generales, nacen los metodos de elementos
espectrales.
Estos metodos de elementos espectrales buscan dividir el dominio de trabajo en elemen-
tos de geometrıas mas sencillas y aplicar esquemas de solucion por metodos espectrales
en cada elemento, lo cual explica su rapida convergencia y su mayor flexibilidad (en
cuanto al dominio de solucion). Sin embargo, resulta mucho mas complicado generar
una implementacion de este metodo porque es necesario generar todo un nuevo esquema
de analisis geometrico tanto al nivel de cada elemento, como al del dominio completo.
Esto ultimo incluye, ademas, la construccion de los elementos de orden elevado, ası como
la seleccion de una familia de funciones base ortogonales que sea apropiada.
En este proyecto se presenta la infraestructura para una implementacion del metodo de
elementos espectrales en el lenguaje Python de manera que se promueva el entendimiento
de las caracterısticas mas relevantes en el desarrollo del metodo, haciendo posible su
aplicacion practica en situaciones reales. Por una parte, se trabajara con problemas
clasicos 1D y 2D con los cuales se pueda comparar su rendimiento con respecto a los
resultados reportados en la literatura, ası como contra alternativas de solucion mas
tradicionales. Estas aplicaciones son, en particular, el flujo de Couette para el caso
1D y el flujo en una cavidad en el caso 2D. Por otra parte, tomando en cuenta las
limitaciones del lenguaje usado, se trabaja brevemente sobre alternativas para acelerar
el codigo, incluyendo la compilacion just-in-time o JIT (durante la ejecucion). Con todo
esto se prepara un repositorio con las funciones necesarias para implementar el metodo
de elementos espectrales en aplicaciones particulares, el cual se encuentra en:
https://github.com/H-Liu/spectral-element-methods
Agradecimientos
Agradezco en primer lugar a mi asesor de esta tesis, Andres Gonzalez, y a mi asesor
del correspondiente proyecto de grado en Matematicas, Mauricio Junca, quienes me
orientaron y apoyaron incondicionalmente a lo largo de esta investigacion. Sus aportes,
criticas, comentarios y sugerencias fueron fundamentales para que el proyecto se llevara
a cabo exitosamente.
Agradezco de igual manera a mis jurados de evaluacion, Omar Lopez y Ahmed Ould,
ya que fue la retroalimentacion que recibı de ustedes la que me permitio identificar y
atacar mis puntos debiles y, ası, mejorar la calidad de mi trabajo.
Agradezco a mis profesores de Ingenieria Mecanica y Matematicas, quienes no solo me
formaron academicamente, sino que tambien me ensenaron a ser una persona ıntegra.
Unicamente a traves de las habilidades desarrolladas a lo largo de cada uno de los cursos
fue que se hizo posible llegar hasta donde estoy.
Agradezco a Sergio Bacca y a mis demas companeros del grupo Robocol, pues mas
que un equipo han sido una familia para mı, exigiendome, comprendiendome y estando
permanentemente dispuestos a escucharme.
Agradezco a mi gran amigo Carlos Carvajal, ası como a todas aquellas personas que han
estado conmigo en las buenas y en las malas, pues ha sido con su apoyo que he podido
superar todos los retos a los que me he enfrentado.
Agradezco finalmente a mi familia, quienes me impulsaron a sonar y a llegar mas alla de
lo que alguna vez creı posible. Nada de esto podria haber sido posible sin sus palabras
de aliento, sin sus grandes exigencias y expectativas.
v
Contenidos
Declaracion de propiedad i
Resumen iii
Agradecimientos v
Contenidos vi
Lista de Figuras viii
Lista de Tablas ix
Sımbolos x
1 Introduccion 1
1.1 Motivacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Contexto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Sobre el metodo de elementos espectrales . . . . . . . . . . . . . . . . . . 3
1.4 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 El Metodo de Elementos Espectrales 5
2.1 Antecedentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.1 Metodos Espectrales . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2 Elementos Finitos . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Fundamentos Teoricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.1 La ecuacion de Navier-Stokes . . . . . . . . . . . . . . . . . . . . . 7
2.2.2 Proyeccion de Galerkin . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.3 Funciones ortogonales y bases nodales . . . . . . . . . . . . . . . . 10
2.2.4 Interpolacion, el termino de error y convergencia espectral . . . . . 12
2.2.4.1 Las funciones de interpolacion . . . . . . . . . . . . . . . 13
2.2.4.2 El termino de error . . . . . . . . . . . . . . . . . . . . . 15
2.2.4.3 Convergencia y la constante de Lebesgue . . . . . . . . . 16
2.2.4.4 Convergencia Espectral . . . . . . . . . . . . . . . . . . . 17
2.3 Generacion de la malla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3.1 Generacion de los elementos . . . . . . . . . . . . . . . . . . . . . . 19
vi
Contenidos vii
2.3.2 Generacion de nodos de interpolacion . . . . . . . . . . . . . . . . 20
2.3.3 Matriz de conectividad . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4 Construccion de la matriz global y el vector del lado derecho . . . . . . . 22
2.4.1 Matrices por elemento . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.4.2 Matriz de difusion global . . . . . . . . . . . . . . . . . . . . . . . 24
2.4.3 Vector derecho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3 Implementacion en 1D 26
3.1 Flujo de Couette . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2 Solucion por elementos espectrales . . . . . . . . . . . . . . . . . . . . . . 27
3.3 Comparacion de resultados . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4 Implementacion en 2D 32
4.1 Flujo con una cavidad rectangular . . . . . . . . . . . . . . . . . . . . . . 32
4.2 Solucion por elementos espectrales . . . . . . . . . . . . . . . . . . . . . . 33
4.3 Analisis de resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3.1 Elementos quadrilaterales con numeracion XY . . . . . . . . . . . 42
4.3.2 Elementos quadrilaterales con numeracion YX . . . . . . . . . . . 42
4.3.3 Elementos triangulares con numeracion cıclica . . . . . . . . . . . . 43
4.3.4 Comparacion de los resultados . . . . . . . . . . . . . . . . . . . . 44
5 Mejoramiento del codigo 48
5.1 Optimizacion manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.2 Lenguajes interpretados y lenguajes compilados . . . . . . . . . . . . . . . 51
5.3 Compilacion Justo a Tiempo (JIT) . . . . . . . . . . . . . . . . . . . . . . 52
6 Conclusiones 54
6.1 Comentarios finales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A Funciones Utilizadas 56
A.1 Implementacion 1D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A.2 Implementacion 2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
B Familias de Funciones Ortogonales 74
B.1 Familias de Funciones 1D . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
B.1.1 Polinomios de Legendre . . . . . . . . . . . . . . . . . . . . . . . . 74
B.1.2 Polinomios de Lobatto . . . . . . . . . . . . . . . . . . . . . . . . . 75
B.1.3 Polinomios de Chevyshev . . . . . . . . . . . . . . . . . . . . . . . 76
B.1.4 Polinomios de Chevyshev del segundo tipo . . . . . . . . . . . . . 77
B.1.5 Polinomios de Jacobi . . . . . . . . . . . . . . . . . . . . . . . . . . 77
B.2 Familias de Funciones 2D . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
B.2.1 Polinomios de Appell . . . . . . . . . . . . . . . . . . . . . . . . . . 79
B.2.2 Polinomios de Proriol . . . . . . . . . . . . . . . . . . . . . . . . . 79
Bibliografıa 81
Lista de Figuras
2.1 Aproximacion a la funcion de Runge para distintos ordenes . . . . . . . . 12
2.2 Constantes de Lebesgue calculadas para distintos numeros de nodos y suscotas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3 Malla ancestral de elementos triangulares con un paso de refinamiento . . 19
2.4 Malla definida por medio de subdivision directa del dominio de solucion . 20
2.5 Diagrama de esparcidad para la matriz de difusion en 1D . . . . . . . . . 25
3.1 Diagrama representativo del flujo de Couette generalizado . . . . . . . . . 26
3.2 Distribucion de los elementos y los nodos de interpolacion correspondi-entes a la malla (2,4,6,5,3,1) . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.3 Diagrama de esparcidad en la matriz del problema . . . . . . . . . . . . . 29
3.4 Soluciones obtenidas para el flujo bajo distintos gradientes de presion . . 30
3.5 Soluciones obtenidas con los nuevos nodos . . . . . . . . . . . . . . . . . . 30
4.1 Diagrama representativo del flujo en la cavidad . . . . . . . . . . . . . . . 32
4.2 Distribucion de los elementos y los nodos de interpolacion correspondi-entes a la malla con 8 elementos en cada direccion y orden 2 en cadacoordenada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.3 Malla correspondiente al caso triangular con 8 elementos por direccion yorden 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.4 Diagrama de esparcidad en la matriz del sistema cuadrilateral XY . . . . 38
4.5 Diagrama de esparcidad en la matriz del sistema para el caso YX . . . . . 38
4.6 Diagrama de esparcidad en la matriz del sistema triangular . . . . . . . . 39
4.7 Solucion obtenida para el flujo en la cavidad con la malla rectangularconstruida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.8 Solucion obtenida para el campo de presiones en la cavidad con la mallaconstruida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.9 Solucion obtenida para el flujo en la cavidad con la malla triangular . . . 40
4.10 Solucion obtenida para el campo de presiones en la cavidad con la mallatriangular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.11 Numeracion en el orden XY . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.12 Patron de esparcidad en el orden XY . . . . . . . . . . . . . . . . . . . . . 43
4.13 Numeracion en el orden YX . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.14 Patron de esparcidad en el orden YX . . . . . . . . . . . . . . . . . . . . . 44
4.15 Numeracion en el orden cıclico . . . . . . . . . . . . . . . . . . . . . . . . 45
4.16 Patron de esparcidad en la numeracion cıclica . . . . . . . . . . . . . . . . 45
4.17 Visualizacion reologica para el flujo en la cavidad . . . . . . . . . . . . . . 46
4.18 Solucion obtenida para el flujo en la cavidad en elementos finitos . . . . . 47
viii
Lista de Tablas
2.1 Familias de funciones conocidas en 1D . . . . . . . . . . . . . . . . . . . . 11
3.1 Errores medidos para distintas mallas . . . . . . . . . . . . . . . . . . . . 31
4.1 Tiempos medidos para la numeracion XY . . . . . . . . . . . . . . . . . . 42
4.2 Tiempos medidos para la numeracion YX . . . . . . . . . . . . . . . . . . 44
4.3 Tiempos medidos para la numeracion triangular . . . . . . . . . . . . . . . 44
B.1 Miembros de la familia de polinomios de Legendre . . . . . . . . . . . . . 75
B.2 Miembros de la familia de polinomios de Lobatto . . . . . . . . . . . . . . 76
B.3 Miembros de la familia de polinomios de Chevyshev . . . . . . . . . . . . 77
B.4 Miembros de la familia de polinomios de Chevyshev del segundo tipo . . . 77
B.5 Miembros de la familia de polinomios de Jacobi . . . . . . . . . . . . . . . 78
B.6 Miembros de la familia de polinomios de Appell . . . . . . . . . . . . . . . 79
B.7 Miembros de la familia de polinomios de Proriol . . . . . . . . . . . . . . 80
ix
Sımbolos
Sımbolo Nombre Unidades
C Matriz de conectividad -
Dij Matriz de difusion (o rigidez) -
cp Capacidad termica J/(kg ·K)
f Vector de fuerzas externas N
Gi Autoproducto interno de funciones ortogonales -
k Conductividad termica W/(m ·K)
Mij Matriz de masa -
Nij Matriz de adveccion -
NE Numero de elementos -
NG Numero de nodos globales -
s Termino de entrada o generacion -
t Tiempo s
~u Vector de velocidad m/s
u, v, w Componentes de velocidad en las direcciones x, y, z m/s
w(~x) Funcion de pesos -
δij Delta de Kroenecker -
ξ, η, ζ Coordenadas elementales estandar -
θ Temperatura K
κ Difusividad termica m2/s
ΛN Constante de Lebesgue -
µ Viscosidad Dinamica Pa · sρ Densidad kg/m3
φ Funcion perteneciente a una base ortogonal -
ψ Funcion de interpolacion estandar -
x
Este trabajo es dedicado a todos aquellos que me acompanarondurante este arduo proceso.
xi
Capıtulo 1
Introduccion
Este primer capıtulo busca introducir la motivacion que conduce al trabajo de investi-
gacion presentado, asi como un breve contexto acerca del mismo. De igual manera se
introducen los objetivos del proyecto.
1.1 Motivacion
En la actualidad, uno de los grandes retos de la humanidad es el de entender a cabal-
idad el comportamiento de los fluidos. Lo anterior radica en que solo a partir de este
conocimiento es posible realizar disenos y generar productos que se adapten a las necesi-
dades presentes en toda clase de aplicaciones. Desde la aerodinamica vehicular hasta
la mecanica de biofluidos, entender las propiedades del flujo permite comprender cuales
son los problemas de disenos actuales y como solucionarlos. Ejemplos ilustrativos de
esta necesidad son el diseno de helices de aerogeneradores y la produccion de injertos
vasculares para capilares sanguıneos. En estos casos, conocer como se comporta el flu-
ido con respecto al producto resulta importante porque permitirıa aprovechar mejor las
corrientes de aire y promoverıa la compatibilidad de los dispositivos con los pacientes
respectivamente.
Sin embargo, debido a las geometrıas complejas que se presentan en la practica, rara
vez existen soluciones analıticas y, por lo tanto, se hace necesario el uso de herramientas
computacionales. Estas permiten obtener soluciones aproximadas mediante el uso de
diversos metodos numericos, cada uno con sus ventajas y desventajas. Algunos de los
mas reconocidos son los metodos de diferencias finitas, los de elementos finitos, y los es-
pectrales. Unos son mas faciles de implementar, otros permiten trabajar con geometrıas
mas complejas, y los ultimos buscan ser especialmente rapidos. En particular, uno de
1
Capıtulo 1. Introduccion 2
los grandes requerimientos que se deben satisfacer es el de brindar una respuesta con
poco error en una cantidad de tiempo razonable. Es por ello que los metodos utilizados
evolucionan permamentemente, siendo uno de los grandes retos la minimizacion de este
tiempo de ejecucion.
1.2 Contexto
En general, existen dos maneras que se utilizan para mejorar la operacion de un metodo:
reducir el numero de calculos que requiere, o aumentar la precision del mismo. Para re-
ducir el numero de calculos necesarios es posible preparar y almacenar los resultados que
se utilizaran reiteradamente, de manera que este tiempo no se perciba constantemente a
lo largo de la solucion si no una unica vez durante la aplicacion del metodo. Por el otro
lado, mejorar la precision del metodo implica realizar un refinamiento, a costa de tener
mas operaciones, o alterar el esquema de solucion por uno de convergencia mas rapida.
En todo caso, no hay que olvidar que se requiere que el metodo sea compatible con la
geometrıa con la que se trabaja. Tomando esto en cuenta, actualmente los metodos mas
populares en la practica son los metodos espectrales y los metodos de elementos finitos,
ya que cada uno ataca a uno de estos dos problemas.
Los metodos espectrales se caracterizan por su rapida convergencia en geometrıas sen-
cillas. Para lograr esto, los metodos utilizan distintas familias de funciones ortogonales
para definir tanto los modos como los nodos de la solucion [1]. Esto es, el metodo
permite trabajar con cada funcion de la familia (descripcion modal), o con los nodos
que genera la misma (descripcion nodal). Como el numero de funciones utilizadas en la
solucion final es bastante reducido, el resultado es una solucion bastante rapida [2]. No
obstante, antes de aplicar el metodo es necesario definir la familia de funciones a utilizar,
ya que cada una presenta ventajas segun el tipo de problema. Esto se traduce en una
gran cantidad de procesamiento que se debe realizar antes de entrar a la solucion. Mas
aun, la mayorıa de las familias unicamente estan definidas para trabajar con geometrıas
bastante sencillas.
Por el otro lado, los metodos de elementos finitos se caracterizan por su versatilidad
incluso en geometrıas bastante complejas. Para lograr este resultado, el metodo comienza
por subdividir el dominio de solucion en una serie de elementos de geometrıa sencilla.
Esto hace que la solucion en cada uno de los elementos sea sencilla y que el problema
radique en acoplar la informacion de nodos comunes [3]. Una vez se organizan los nodos
y sus interacciones, el resto de la solucion es bastante sencilla, por lo que no se requiere
mayor procesamiento antes de entrar a solucionar el sistema completo. En contraste,
Capıtulo 1. Introduccion 3
como la solucion en cada elemento usualmente no es particularmente precisa, el metodo
acaba por presentar tasas de convergencia mas lentas.
1.3 Sobre el metodo de elementos espectrales
En vista de lo anterior, un metodo que combina las ventajas de ambos es el metodo
de elementos espectrales. De manera sencilla, este metodo consiste en la discretizacion
del dominio en elementos y la solucion por metodos espectrales en cada uno [1]. De
esta manera, el enmallado permite conservar la versatilidad de los metodos de elementos
finitos, mientras que la solucion por metodos espectrales en cada elemento preserva la
convergencia espectral. Es por estas virtudes que, para un mismo numero de elementos,
el resultado final presenta errores mucho menores que en metodos tradicionales. De
hecho, este error cae exponencialmente [3], por lo que la complejidad computacional, ası
como la cantidad de procesos y la velocidad de los mismos, son mucho menores que en
metodos comparables. Estos metodos son estudiados ampliamente en [4, 5].
Ahora bien, es importante notar que este metodo no trae unicamente ventajas. La
implementacion de este tipo de metodo requiere la utilizacion de elementos de orden
elevado, lo cual significa que es necesario definir las funciones a partir de las cuales se
definen los nodos intermedios. En particular, como se indico para los metodos espec-
trales, estas funciones deben formar una familia ortogonal que ademas sea apropiada
para el esquema de solucion planteado [3], ya que solo ası se asegura la convergencia
del metodo. Por otra parte, el metodo de elementos espectrales requiere que el acople
entre los distintos elementos se realice de una manera sencilla para que el sistema global
resultante sea facil de solucionar, algo que depende fuertemente de la manera en que se
realice el proceso de enmallado.
1.4 Objetivos
Objetivo General:
Desarrollo de una implementacion del metodo de elementos espectrales en el lenguaje
Python que permita entender las caracterısticas mas relevantes en la adopcion de estos
metodos, buscando reducir el tiempo de solucion en aplicaciones practicas.
Objetivo Especıficos:
• Descripcion detallada de los fundamentos teoricos del metodo de elementos espec-
trales que permita identificar los retos existentes en la implementacion del mismo.
Capıtulo 1. Introduccion 4
• Generacion de una aplicacion del metodo en 1D que sea consistente con soluciones
analıticas clasicas como el flujo de Couette generalizado.
• Generacion de una aplicacion del metodo en 2D que sea consistente con soluciones
analıticas clasicas como el flujo en una cavidad cuadrada.
• Utilizacion de las librerıas de aceleracion de codigo por medio de compilacion just-
in-time para mejorar los tiempos de ejecucion de los codigos.
• Creacion y documentacion de un repositorio Git publico que permita a otros usuar-
ios utilizar las funciones desarrolladas en sus propias implementaciones.
Capıtulo 2
El Metodo de Elementos
Espectrales
Para comenzar a trabajar sobre el metodo de elementos espectrales es fundamental
considerar primero los antecedentes que condujeron al mismo. De acuerdo con lo que se
menciono anteriormente, tradicionalmente se han usado (en la practica) los metodos de
diferencias finitas, de volumenes finitos, de elementos finitos o los metodos espectrales
entre otros. Sin embargo, si bien cada uno de ellos trae sus ventajas y desventajas
particulares, se estudian mas detalladamente los metodos espectrales y los de elementos
finitos. Esto radica en que justamente son estas dos familias las que dan a lugar al
metodo a desarrollar.
En este capıtulo se discuten particularmente los puntos relevantes tanto de los metodos
espectrales, como de los de elementos finitos. En particular se mencionan los compo-
nentes y fundamentos teoricos principales de los metodos y las aplicaciones de estos
conceptos en la optica de los elementos espectrales para comenzar a desarrollar for-
malmente la implementacion correspondiente. Teniendo ya los fundamentos teoricos
correspondientes a una solucion espectral, es posible plantear mas puntualmente los pa-
sos necesarios para obtener una implementacion de un metodo por elementos, ya sea de
elementos finitos o espectrales. Estos pasos corresponden puntualmente a la generacion
de la malla de nodos de interpolacion y a la construccion de las matrices globales del
problema (la cual se construye a partir de las matrices correspondientes a cada ele-
mento). En el Capıtulo 3 y el Capıtulo 4 se presentan los ejemplos de aplicacion de esta
infraestructura.
5
Capıtulo 2. El Metodo de Elementos Espectrales 6
2.1 Antecedentes
2.1.1 Metodos Espectrales
Los metodos espectrales reciben su nombre debido a las altas tasas de convergencia que
tiene el error de truncado (la tasa es espectral, o mas rapida que cualquier potencia de
1/N). En este tipo de metodo la idea fundamental corresponde a la aproximacion de las
soluciones a las ecuaciones diferenciales por series finitas de funciones ortogonales, las
cuales provienen de distintos contextos. En particular, este tipo de funcion incluye las
exponenciales complejas (en las series de Fourier) para casos periodicos, o los polinomios
de Chebyshev o Legendre para los casos no periodicos. Debido a esto, las tres elecciones
crıticas a la hora de definir un metodo espectral son las siguientes: la escogencia de
la familia de funciones base sobre las que se van a expandir la solucion, la manera
de describir la expansion (i.e. descripcion nodal y modal) y el proceso con el que se
determinan las incognitas del problema (e. g. colocacion o proyeccion de Galerkin como
parte de una metodologia de residuos ponderados) [1].
Esta familia de metodos ha sido ampliamente estudiada en [1, 2] y ha permanecido rele-
vante por su gran velocidad de solucion. Sin embargo, su mayor limitacion corresponde
a la necesidad de tener una geometria sencilla sobre la cual operar, dado que al tener
dominios con geometrias mas complejas de hace mas dificil mantener las propiedades de
ortogonalidad y suavidad de las funciones en el dominio.
De acuerdo con la primera decision, y como se menciono en la descripcion previa, es
imperativo que las funciones seleccionadas cumplan con un criterio de ortogonalidad (o
por lo menos semi-ortogonalidad) ya que esto es lo que garantiza el caracter espectral
del metodo como se vera a continuacion en la seccion correspondiente. Asi mismo, la
descripcion de la expansion define el tipo de solucionador obtenido y la determinacion
de incognitas define cuan complejo es el problema a resolver finalmente.
2.1.2 Elementos Finitos
Los metodos de elementos finitos han sido ampliamente acogidos para ser usados en
una gran variedad de aplicaciones debido a su alta versatilidad. Estos metodos son,
en principio, aplicables en casi cualquier tipo de geometria y para casi cualquier tipo
de problema o ecuacion (aunque funcionan mejor en problemas del tipo de la ecuacion
de difusion, que en problemas del tipo de la ecuacion de conveccion [3]). Su nombre
proviene del hecho de que en lugar de trabajar sobre el dominio de solucion completo di-
rectamente, se utilizan unidades sencillas (tıpicamente polıgonos o polihedros convexos)
Capıtulo 2. El Metodo de Elementos Espectrales 7
llamadas elementos finitos. En particular, ejemplos populares de discretizaciones in-
cluyen el refinamiento sucesivo de una malla maestra, o la triangulacion de Delaunay.
Las mallas resultantes son estructurada y no estructurada (que permite la adicion o
remocion de elementos sin afectar necesariamente a los otros nodos o su numeracion)
respectivamente. Debido a lo anterior, las elecciones cruciales a la hora de definir un
metodo de elementos finitos (y que no se mencionaron al tratar con los metodos espec-
trales) son las siguientes: la escogencia de los nodos de interpolacion o la definicion de
la malla, la manera de numerar los nodos ina vez se define la malla, y la manera en que
se ensamblan los elementos en la matriz del problema [6].
Esta familia de metodos ha sido ampliamente estudiada por [6, 7] y ha sido la herramienta
fundamental en la mayorıa de los software de simulacion numerica. Sin embargo, su
mayor limitacion corresponde a la sensibilidad con respecto a la definicion de la malla
(distintas mallas significan distintos tiempos de solucion) y a la necesidad de tiempos
extensos para lograr altas precisiones. Esto es, para alcanzar una cierta precision, se
puede requerir un alto numero de elementos, lo cual a su vez se traduce en largos tiempos
de solucion (ya que su tasa de convergencia suele ser del orden de 1/Nk [3]).
2.2 Fundamentos Teoricos
Teniendo una idea gruesa del funcionamiento de estos metodos, es posible entrar a tra-
bajar sobre los fundamentos teoricos de interes para el desarrollo de la implementacion.
Para guiar este proceso, se estudia paralelamente la ecuacion de Navier-Stokes como el
caso de referencia por excelencia. En particular, se profundiza sobre la proyeccion de
Galerkin como forma de obtener una version debil del problema, y en la utilizacion de
familias de funciones ortogonales como bases nodales. Cabe anotar que, si bien una
descripcion modal es tambien posible, no se hara mayor enfasis en la misma.
2.2.1 La ecuacion de Navier-Stokes
Las ecuaciones de Navier-Stokes son un conjunto de ecuaciones diferenciales parciales
no lineales de segundo orden que describen el movimientos de un fluido newtoniano (con
viscosidad constante en el tiempo). Dada la alta complejidad del problema en su forma
mas general, en esta ocasion se considera unicamente el caso de densidad constante (i. e.
fluido incompresible) y uniforme [3]. De acuerdo con lo anterior, la formulacion vectorial
Capıtulo 2. El Metodo de Elementos Espectrales 8
de estas ecuaciones sobre un dominio predeterminado D corresponde a:∂ρ∂t +∇ · (ρ~u) = 0 → ∇ · ~u = 0
ρ(∂~u∂t + ~u · ∇~u
)= ρ~f −∇p+ µ∇2~u,
(2.1)
donde ∇ · ~u = 0 representa la ecuacion de continuidad que se debe satisfacer en el
fluido para que el problema tenga un sentido fısico. Cabe anotar que esta ecuacion
debe estar sujeta a unas condiciones de fronteras especificas para que la solucion sea
efectivamente unica. Adicionalmente, ∇~u, ∇ · ~u y ∇2~u representan el gradiente, la
divergencia y el laplaciano del vector de velocidad respectivamente. Esto hace que las
ecuaciones resultantes se parezcan bastante a la ecuacion de conveccion-difusion, otro
de los problemas clasicos ampliamente estudiados. Esta se describe por
∂θ
∂t+ ~u · ∇θ = κ∇2θ +
s
ρcp. (2.2)
Dado que aun en esta formulacion el problema no es facil de solucionar, existen una serie
de consideraciones que se pueden hacer para simplificar esta formulacion [8]. Segun el
problema a trabajar, es posible:
• Eliminar los terminos no lineales (~u · ∇~u ≈ 0) cuando los efectos inerciales son
despreciables, es decir, cuando el numero de Reynolds es significativamente bajo
(Re� 1). Este tipo de flujo tambien se conoce como flujo de Stokes.
• Eliminar los terminos dependientes del tiempo(∂·∂t = 0
)cuando el fluido se en-
cuentra en estado estacionario.
• Asumir que el gradiente de presion es constante (∇p = cte.) en flujos completa-
mente desarrollados.
• Despreciar los efectos de las fuerzas externas(~f = 0
)como la gravedad o los
efectos de borde debido a su caracter local-uniforme sobre el dominio completo
(este termino se puede combinar con el gradiente de presion para dar lugar a una
presion modificada en lugar de omitirse).
Para efecto de los casos estudiados, se omite el termino de fuerzas externas al incorpo-
rarlo como un modificador en la presion. Adicionalmente se trabajo con la version lineal
(omitiendo los efectos inerciales) estable de los problemas para tener un problema mas
sencillo de tratar, con soluciones menos caoticas y, por lo tanto, mejor caracterizadas
Capıtulo 2. El Metodo de Elementos Espectrales 9
[9]. La ecuacion resultante es entonces:∇ · ~u = 0
0 = −∇p+ µ∇2~u,(2.3)
2.2.2 Proyeccion de Galerkin
De acuerdo con los pasos requeridos para la aplicacion de cualquier metodo numerico,
debe existir algun metodo que permita realizar la transicion del dominio continuo al
dominio discreto. Una de las posibilidades para hacer esto corresponde al metodo de
residuales ponderados (o weighted residuals). En estos casos se analiza el residual re-
sultante de la aproximacion de la funcion objetivo original por su version interpolada
y, de acuerdo con las ecuaciones resultantes, es necesario definir los pesos correspondi-
entes a cada punto de interes. La proyeccion de Galerkin es una de las versiones mas
populares de estos metodos, ya que los pesos se definen justamente con las funciones de
interpolacion correspondientes a los nodos de interes.
Para el caso especıfico de las ecuaciones de Navier-Stokes es importante notar que las
incognitas no corresponden unicamente a las velocidades: tambien es necesario determi-
nar los valores de las presiones. De acuerdo con esto, se definen nodos de interpolacion
de velocidad y de presion, con sus respectivas funciones de interpolacion φui y φpj . Se
usan entonces las funciones de interpolacion de velocidad con la ecuacion de Navier-
Stokes, mientras que las de presion se asignan a la ecuacion de continuidad. El resultado
obtenido son las ecuaciones ∫Dφpi∇ · ~u dV = 0 (2.4)
y ∫Dφui ρ
(∂~u
∂t+ ~u · ∇~u
)dV =
∫Dφui(−∇p+ µ∇2~u
)dV , (2.5)
sobre el dominio del flujo D. Con ayuda de la definicion del operador ∇2 y el teo-
rema de divergencia de Gauss es posible reexpresar el segundo termino de la integral en
Ecuacion 2.5 para obtener en su lugar:∫Dφui (∇2~u) dV =
∫Dφui (∇ · ∇~u) dV
=
∫D∇ · (φui∇~u) dV −
∫D∇φui · ∇~u dV (2.6)
= −∮∂D
φui ~n · ∇~u dS −∫D∇φui · ∇~u dV .
Capıtulo 2. El Metodo de Elementos Espectrales 10
Similarmente, para el termino de presion de la misma integral en Ecuacion 2.5, se obtiene
que: ∫Dφui∇p dV =
∫D∇(φui p) dV −
∫D∇φui p dV
= −∮∂D
φui p~n dS −∫D∇φui p dV . (2.7)
De esta manera, es posible reescribir finalmente la Ecuacion 2.5, usando los resultados
de Ecuacion 2.6 y Ecuacion 2.7, como:∫Dφui ρ
(∂~u
∂t+ ~u · ∇~u
)dV =
∮∂D
φui p~n dS−µ∮∂D
φui ~n·∇~u dS+
∫D∇φui p dV−µ
∫D∇φui ·∇~u dV .
(2.8)
Esta es una forma general de la ecuacion que se puede aplicar directamente a los casos
particulares estudiados, lo cual arroja como resultado un sistema de ecuaciones a re-
solver. De manera puntual, cuando se trabaja con el flujo de Stokes (despreciando los
terminos no lineales), la ecuacion resultante es:
0 =
∮∂D
φui p~n dS − µ∮∂D
φui ~n · ∇~u dS +
∫D∇φui p dS − µ
∫D∇φui · ∇~u dV . (2.9)
2.2.3 Funciones ortogonales y bases nodales
Finalmente, es necesario mencionar la ultima eleccion importante en los metodos es-
pectrales: la seleccion de la familia ortogonal a usar. Para este efecto se introduce el
producto interno < ·, · >w estandar con pesos en el espacio de funciones integrables.
Definicion 2.1. Dadas dos funciones f1, f2 integrables en el intervalo [c, d] y una funcion
de pesos positiva w(x), se dice que las funciones son ortogonales (con respecto a w(x))
si:
< f1, f2 >w:=
∫ d
cf1(x)f2(x)w(x) dx =
Gi si i = j
0 si i 6= j
donde Gi 6= 0.
De acuerdo con esta definicion, dada cualquier base del espacio de funciones integrables
en un intervalo [c, d] fijo, es posible construir una familia de funciones ortogonales me-
diante el proceso de Gram-Schmidt. De este modo, existe una infinidad de posibles
familias, aunque no todas son particularmente utiles para los metodos espectrales. La
Tabla 2.1 presenta las familias ortogonales mas conocidas para el caso unidimensional, y
Capıtulo 2. El Metodo de Elementos Espectrales 11
Familia Sımbolo [c, d] w(t) GiChevyshev Ti(t) [−1, 1] 1√
1−t2 G0 = π,Gi = π2
Chevyshev segundo tipo Ti(t) [−1, 1]√
1− t2 π2
Hermite Hi(t) (−∞,∞) exp(−t2)√π2ii!
Jacobi J(α,β)i (t) [−1, 1] (1− t)α(1− t)β (*)
Laguerre Li(t) [0,∞) exp(−t) (i!)2
Legendre Li(t) [−1, 1] 1 22i+1
Lobatto Loi(t) [−1, 1] 1− t2 2(i+1)(i+2)2i+3
Radau Ri(t) [−1, 1] 1 + t 2i+1
(*) Gi = 2α+β+1
i!Γ(i+1+α)Γ(i+1+β)
(2i+1+α+β)Γ(i+1+α+β)
Tabla 2.1: Familias de funciones conocidas en 1D (Adaptado de [3])
el Apendice B las descripciones formales de las mismas. Para los metodos a desarrollar,
las familias mas relevantes son las de polinomios de Lobatto (Tabla B.2) y Chevyshev
de segundo tipo (Tabla B.4). Por su parte, en el caso bidimensional hay dos situaciones.
Para dominios cuadrilaterales, los polinomios usados son productos tensoriales de los
polinomios unidimensionales, de manera que no vale la pena mencionarlos nuevamente.
Mientras tanto, para dominios triangulares, las familias mas conocidas son las de Appell
y Proriol [10].
El gran interes de usar estas familias radica en que, al satisfacer la propiedad de ortogo-
nalidad sobre todo el dominio, esencialmente se tiene una base del espacio, permitiendo
asi describir exactamente cualquier funcion, particularmente las funciones de interpo-
lacion. Sin embargo, dado que los recursos de calculo que se tienen son limitados, no es
posible considerar a todos los miembros de la familia (o modos), si no unicamente a los
primeros miembros. Es por eso que se buscan familias donde la magnitud de los modos
subsguientes tienda a 0 para cualquier funcion de interes [1].
Mas aun, si los nodos de interpolacion coninciden con los ceros de estas familias, se
obtiene una ubicacion estrategica de los mismos que hace que el sistema se comporte
bien y no sufra de efectos como las oscilaciones de Runge. Este efecto se representa en la
Figura 2.1, donde un mayor orden de interpolacion no se corresponde una mejor aprox-
imacion a la funcion debido a los picos hacia los extremos (para nodos de interpolacion
uniformemente espaciados).
Puntualmente, los casos ideales corresponden a las familias que buscan minimizar la
norma del error o de la constante de Lebesgue (definida a continuacion). Para el
caso unidimensional estas corresponden justamente a los puntos de Chevyshev y Fekete
Capıtulo 2. El Metodo de Elementos Espectrales 12
Figura 2.1: Aproximacion a la funcion de Runge para distintos ordenes
(equivalentes a los nodos de Lobatto) respectivamente. Estas tienen la propiedad de que
‖ψi(ξ)‖∞ ≤ 1 y ‖ψi(ξ, η)‖∞ ≤ 1 ∀ξ, η (2.10)
en 1D y 2D respectivamente, con igualdad unicamente en el caso ξ = ξi, η = ηi (donde
ξi o (ξi, ηi) corresponden a las coordenadas del i-esimo nodo de interpolacion). Esto se
traduce en que el crecimiento de la funcion de interpolacion se ve acotado, y por lo tanto
se asegura una rapida convergencia en la interpolacion con respecto al orden polinomial
de la misma, como se vera en la seccion siguiente.
2.2.4 Interpolacion, el termino de error y convergencia espectral
Teniendo claras la forma que se va a trabajar de la ecuacion de Navier-Stokes (i.e.
como ecuacion de Stokes) y que familias de funciones se usaran tanto para los casos 1D
(Lobatto) y 2D (Proriol), es necesario entrar a considerar formalmente la manera de
construir y manipular las funciones de interpolacion. Una vez es claro lo anterior, es
posible entrar a tratar con termino de error y analizar la convergencia resultante.
Capıtulo 2. El Metodo de Elementos Espectrales 13
2.2.4.1 Las funciones de interpolacion
Si bien existen distintos tipos de funciones de interpolacion, las mas comunes son las poli-
nomiales debido a su mayor facilidad para ser operadas (e. g. derivacion o integracion).
Particularmente, es tambien importante notar que los polinomios de interpolacion es-
tandar (i. e. definidos sobre los dominios estandar) de un orden determinado son unicos
para un conjunto de nodos apropiado. Es por esto que se puede asegurar una alta consis-
tencia y repetibilidad independientemente de la forma de caracterizarlos y construirlos.
Sin embargo, de acuerdo con la necesidad que exista, la manera de aproximarse puede
llegar a facilitar o dificultar su procesamiento.
Interpolacion en 1D
Para el caso unidimensional, tıpicamente existen dos maneras de construir las funciones
de interpolacion. Estas son las diferencias divididas de Newton y los polinomios de
interpolacion de Lagrange. La primera es especialmente util en contextos de exploracion
o cuando se requiere un procesamiento recursivo de los datos, de manera que es posible
estimar facilmente el error en funcion de los puntos que no se hayan incluido todavia.
Sin embargo, esto mismo hace que la implementacion sea ligeramente mas complicada
y que no sea tan facil de operar. De manera general, si la funcion a interpolar es f(x)
y los nodos sobre los que se interpola x0, x1, . . . , xn, su formulacion se puede expresar a
partir de
ψn(x) = b0 + b1(x− x0) + · · ·+ bn(x− x0)(x− x1) · · · (x− xn−1), (2.11)
donde bi = f [xi, xi−1, . . . , x1, x0] y se definen recursivamente
f [xj ] = f(xj)
f [xj+1, xj ] =f [xj+1]−f [xj ]xj+1−xj
· · ·
f [xj+k, xj+k−1, . . . , xj ] =f [xj+k,xj+k−1,...,xj+1]−f [xj+k−1,xj+k−2,...,xj ]
xj+k−xj
.
Esta definicion hace evidente su naturaleza recursiva y la necesidad que construir las
funciones de interpolacion de ordenes menores.
Por su parte, la interpolacion de Lagrange permite obtener de una manera rapida y
directa la funcion resultante dados los nodos y sus valores respectivos. Esto significa un
numero menor de calculos requeridos y, por lo tanto una mayor velocidad de calculo.
Capıtulo 2. El Metodo de Elementos Espectrales 14
En este caso, se observa que
ψn(x) =n∑i=0
f(xi)`ni (x) =
n∑i=0
f(xi)n∏j=0j 6=i
ξ − ξjξi − ξj
. (2.12)
En este caso `ni (x) :=∏nj=0j 6=i
ξ−ξjξi−ξj corresponde al polinomio de Lagrange, que satisface
`i(xj) = δij . Esta forma no solo permite un calculo mucho mas directo de los polinomios,
si no que permite operarlos de una manera mucho mas facil (usando reglas de derivacion
de productos o, inclusive, derivacion logarıtmica), como se refleja en el Capıtulo 3 y en
el Capıtulo 4.
Interpolacion en 2D
Por el otro lado, para el caso bidimensional, la situacion no siempre resulta tan sencilla.
Unicamente para distribuciones especiales es posible factorizar la funcion de interpo-
lacion de manera que cada factor dependa exclusivamente de una de las coordenadas.
En estos casos, cada uno de los factores se acaba comportando como una funcion de
interpolacion unidimensional y, por lo tanto, se puede tratar como se describio en el
apartado anterior. Ejemplos de esto son distribuciones en mallas para dominios cuadra-
dos (u otros cuadrilateros) y la distribucion uniforme en el triangulo.
Para el caso del cuadrado, si la funcion a interpolar es f(ξ, η) y los nodos de interpolacion
son (ξi, ηj) ∀i ∈ {0, 1, . . . ,m}, j ∈ {0, 1, . . . , n} (para un total de (m + 1)(n + 1) nodos
de interpolacion), el resultado se puede describir como:
ψ(ξ, η) =
m∑i=0
n∑j=0
f(ξi, ηj)`mi (ξ)`nj (η) =
m∑i=0
n∑j=0
f(ξi, ηj)
m∏k=0k 6=i
ξ − ξkξi − ξk
n∏l=0l 6=j
η − ηkηj − ηk
.
(2.13)
Por el contrario, para los casos mas generales es necesario utilizar una estrategia difer-
ente. En estos casos se tienen nodos de interpolacion (ξ1, η1), (ξ2, η2), . . . , (ξN , ηN ) y se
busca construir primero las funciones para cada nodo tales que ψ∗i (ξj , ηj) = δij y, por lo
tanto ψ(ξ, η) =∑N
i=1 f(ξi, ηi)ψ∗i (ξ, η). Estas funciones se ven de la forma
ψ∗i (ξ, η) = cNφ1(ξ, η) + cN−1φ2(ξ, η) + · · ·+ c1φN (ξ, η) (2.14)
donde N es el numero de nodos, y los φj son miembros de una base polinomial apropi-
ada. Para describir este problema mas facilmente, se utiliza la matriz de Vander-
monde generalizada (Vφij = φi(ξj , ηj)) de manera que, si ~c = (cN , cN−1, . . . , c1)T , ~ei =
Capıtulo 2. El Metodo de Elementos Espectrales 15
(0, 0, . . . , 1, . . . , 0)T el i-esimo vector canonico, φ(ξ, η) = (φ1(ξ, η), φ2(ξ, η), . . . , φN (ξ, η))
y ψ∗(ξ, η) = (ψ∗1(ξ, η), ψ∗2(ξ, η), . . . , ψ∗N (ξ, η)), entonces:
V Tφ · ~c = ~ei ⇔ ~c = V T
φ−1 · ~ei
⇔ ψ∗i (ξ, η) = φ(ξ, η) · V Tφ−1 · ~ei
⇔ ψ∗(ξ, η) = Vφ−1 · φ(ξ, η)
⇔ Vφ · ψ∗(ξ, η) = φ(ξ, η) (2.15)
de acuerdo con [3]. Esta ultima, la Ecuacion 2.15, representa un sistema lineal que
permite describir a ψ∗i mediante la regla de Cramer por:
ψ∗i (ξ, η) =Det [Vφ(ξ1, η1, ξ2, η2, · · · , ξi−1, ηi−1, ξ, η, ξi+1, ηi+1, · · · , ξN , ηN )]
Det [Vφ(ξ1, η1, ξ2, η2, · · · , ξN , ηN )]. (2.16)
En este caso la matriz del numerador corresponde a sustituir la i-esima columna por las
mismas funciones pero evaluadas en (ξ, η) en lugar de (ξi, ηi).
2.2.4.2 El termino de error
Se observa que, en general, el error del metodo viene dado en su mayor parte por el error
en la interpolacion. Esto sucede por que el error de calculo es cuantificable y dependi-
ente de la tecnologıa usada y, adicionalmente, es posible realizar una integracion exacta
(con respecto a la funcion interpolada) bajo una cuadratura adecuada. Es por ello que
en esta seccion se trabaja sobre el termino de error correspondiente especıficamente a la
interpolacion, y sobre la constante de Lebesgue. Estos dos valores caracterizan el com-
portamiento y, en particular, la convergencia del metodo. Por su mayor facilidad para
ser descrito, se trabaja exclusivamente con el caso unidimensional, pero los resultados
se pueden extender al caso bidimensional naturalmente.
Si la funcion a interpolar es f(x) ∈ CN+1([c, d]) y el polinomio resultante de la inter-
polacion es PN (x) al usar los nodos x0, x1, . . . , xN , se observa que el termino de error,
definido por
e(x) = PN (x)− f(x), (2.17)
pertenece a CN+1([c, d]) y se puede reescribir como:
e(x) = −f(N+1)(ξ)
(N + 1)!ΦN+1(x) (2.18)
donde ΦN+1(x) =∏Ni=0(x− xi) con ξ ∈ (c, d).
Capıtulo 2. El Metodo de Elementos Espectrales 16
2.2.4.3 Convergencia y la constante de Lebesgue
Teniendo clara la manera en que se puede tratar el termino de error, es necesario dotar
al espacio de funciones continuas con una norma para entrar a discutir sobre la nocion
de convergencia. En este caso, se usara la norma del maximo ‖f‖∞ = maxx∈[c,d] |f(x)|.Al considerar esta norma, es sabido [3] que entre los polinomios de orden N existe un
polinomio POptN (x) (no necesariamente de interpolacion para los nodos dados) que min-
imiza el error ‖e(x)‖ = ‖POptN (x)− f(x)‖. A este error se le conoce como error minimax
y se denota tambien por ρN [f(x)]. Esto permite describir el error de interpolacion por:
‖e(x)‖ = (1 + ‖PN‖∞)ρN [f(x)], (2.19)
con ‖PN‖ := max‖f‖=1 (‖PN (x)‖) [11]. Faltarıa entonces caracterizar el termino ‖PN‖,para lo cual se introduce la constante de Lebesgue.
Si se consideran los polinomios de Lagrange de orden N (i. e. con N + 1 nodos de
interpolacion) correspondientes a los nodos xi (denotados por `Ni (x) como antes), se
puede definir la funcion de Lebesgue por
LN (x) :=
N∑i=0
|`Ni (x)|, (2.20)
y el maximo valor que alcanza como
ΛN := max(LN (x)), (2.21)
conocido como la constante de Lebesgue. Esta constante depende unicamente de las
posiciones de los nodos de interpolacion y se relaciona con el termino anterior, ‖PN‖, de
acuerdo con:
‖PN‖ = max‖f‖=1,x
(‖PN (x)‖)
= max‖f‖=1,x
(|N∑i=0
f(xi)`Ni (x)|
)
≤ max‖f‖=1,x
(N∑i=0
|f(xi)||`Ni (x)|
)
≤ maxx
(N∑i=0
|`Ni (x)|
)= max
x(LN )
= ΛN (2.22)
Capıtulo 2. El Metodo de Elementos Espectrales 17
Combinando la Ecuacion 2.19 con la Ecuacion 2.22, el resultado final es
‖e(x)‖ ≤ (1 + ΛN )ρN [f(x)]. (2.23)
Con respecto a esta formulacion, los teoremas de Jackson y Erdos presentan cotas para
el error minimax y para la constante de Lebesgue respectivamente [3]. Particularmente,
el primer teorema de Jackson indica que
ρN [f(x)] ≤(
1 +π2
2
)max
|x−y|≤1/N|f(x)− f(y)|, (2.24)
de manera que si la funcion resulta ser Holder con exponente α (|f(x)−f(y)| ≤ A|x−y|α
para constantes A,α > 0), el error minimax decrece a una tasa de al menos 1/Nα. Por
otra parte, la cota inferior propuesta por Erdos corresponde a
ΛN >2
πln(N + 1)− c, (2.25)
siendo c > 0 una constante [11]. Esto ultimo indica que la misma tendera a crecer
inevitablemente a tasas por lo menos logarıtmicas.
De acuerdo con esto, el error convergera (uniformemente) en la medida en que el crec-
imiento de la constante de Lebesgue sea menor a la tasa de decrecimiento del error
minimax.
2.2.4.4 Convergencia Espectral
Teniendo ya claros los conceptos de error y de la constante de Lebesgue, es posible entrar
a considerar las maneras de minimizar el error (a partir de la seleccion de los nodos de
interpolacion). Si bien definir los nodos de interpolacion como los ceros de los polinomios
de Chevyshev permite minimizar la norma (como se observa en el Apendice B), estos
ceros no incluyen los extremos del intervalo. Ahora, aunque en metodos espectrales esto
no genera inconvenientes, al hablar de metodos de elementos espectrales es necesario
que existan nodos compartidos en las fronteras, garantizando la continuidad de las solu-
ciones entre dominios adjacentes (i. e. elementos adjacentes) [3]. Es por esto que al
justificar la utilizacion de los metodos espectrales en la practica se habla tambien de los
puntos de Fekete (que en el caso unidimensional coinciden con los nodos de interpolacion
correpsondientes a los ceros de Lobatto completados con -1 y 1).
Para el caso unidimensional, utilizar los puntos de Fekete (ceros de Lobatto completados
con x0 = −1 y xN = 1), corresponde a obtener polinomios de interpolacion que convergen
Capıtulo 2. El Metodo de Elementos Espectrales 18
uniforme y exponencialmente. Para esto, se puede mostrar que
‖e(x)‖ ≤(
1 +√N + 1
) A
Nα∼ K
√N
Nα
N→∞→ 0, (2.26)
siendo K una constante (correspondiente a convergencia uniforme) y que
‖e(x)‖ ≤(
1 +
(2
πln(N + 1) + 0.685
))A
Nα∼ K lnN
Nα, (2.27)
donde se puede apreciar una tasa de convergencia mayor a cualquier potencia 1/Nβ. Al
pasar a dos (o mas) dimensiones, nuevamente se presentan los puntos de Fekete como
las posiciones optimas para la escogencia de los nodos de interpolacion, como se aprecia
en [12, 13]. Sin embargo, para el caso triangular le siguen de cerca las mallas de nodos
generados a partir de los polinomios de Chevishev del segundo orden y de Lobatto para
ordenes no muy altos, de acuerdo con lo presentado en [12].
Figura 2.2: Constantes de Lebesgue calculadas para distintos numeros de nodos ysus cotas
2.3 Generacion de la malla
Como se expreso previamente, el componente principal de cualquier metodo de solucion
por elementos, que adicionalmente marca la precision y calidad de la solucion, corre-
sponde a la generacion de la malla de nodos con respecto a los cuales se trabaja. A
excepcion del caso lineal, en que los nodos se encuentran unicamente en los vertices
de las fronteras entre elementos, esto se realiza en dos pasos: primero se definen los
elementos a usar y posteriormente se construye en cada uno de ellos la totalidad de
Capıtulo 2. El Metodo de Elementos Espectrales 19
los nodos de interpolacion. Sin embargo, dado que es necesario identificar nodos co-
incidentes entre elementos adjacentes para implementar las condiciones de frontera, se
utiliza un recurso adicional. Este se denomina matriz (o tabla) de conectividad y per-
mite relacionar la numeracion global que reciben los nodos, con la numeracion interna
o local a cada elemento. A continuacion se trata cada uno de estos puntos de manera
independientemente.
2.3.1 Generacion de los elementos
En general, la construccion de los elementos se puede realizar de distintas maneras,
siendo las mas populares las indicadas anteriormente (usando mallas ancestrales que se
van refinando o la triangulacion de Delaunay y sus equivalentes en otros dominios [3]) y
el uso de la geometrıa del dominio completo (cuando el mismo no es muy complejo). La
primera alternativa, el uso de una malla ancestral, suele no ser ideal pues, ademas de que
se requiere la definicion de los elementos ancestrales, su crecimiento es bastante limitado
(i. e. se subdivide cada elemento de una misma manera, resultando en una malla cuyos
numeros de elementos son un multiplo de la cantidad de elementos preexistentes). A
modo de ejemplo, si la malla original consta de 8 elementos triangulares sobre un dominio
rectangular, y el paso de refinamiento consiste en construir nuevos elementos tomando
los puntos medios de las fronteras de los elementos definidos previamente, el numero de
elementos se multiplica por 4 y, por lo tanto, siempre se tiene una potencia de 2 como
numero de elementos (asi como de divisiones en cada dimension (Figura 2.3).
Figura 2.3: Malla ancestral de elementos triangulares con un paso de refinamiento
Otra estrategia de construccion, especialmente adecuada para dominios de geometrias
no muy complejas, corresponde a la subdivision uniforme de la malla. Es decir, realizar
un proceso similar al anterior, pero directamente sobre la totalidad del dominio. En este
caso, la malla se puede refinar por distintas cantidades sobre cada dimension, haciendo
la malla resultante mucho mas versatil (e. g. con mas divisiones sobre la dimension de
Capıtulo 2. El Metodo de Elementos Espectrales 20
mayor longitud). La Figura 2.4 presenta dos ejemplos de enmallado para un sistema
rectangular.
Figura 2.4: Malla definida por medio de subdivision directa del dominio de solucion
Finalmente, la estrategia de construccion de mallas no estructuradas conocida como
triangulacion de Delaunay es adecuada para dominios generales. En este caso se definen
primero los vertices de los elementos y, a partir de ellos, se construyen los elementos
correspondientes. Sin embargo, por el numero adicional de procesos que se requieren,
toma un tiempo mas largo que el de las estrategias anteriores. Una implementacion
de esta discretizacion se encuentra en [3]. se evitano es apta y el uso de mallas no
estructuradas.
En todo caso, de acuerdo con la malla definida, es posible que se afecte no solo la facilidad
de resolucion del sistema, si no propiedades intrinsecas de la solucion, incluyendo la
anisotropıa (i. e. dependencia en la orientacion del elemento). Para asegurar que
la solucion es fisicamente viable, se requiere satisfacer la continuidad de la misma a
traves de los elementos. Esto se garantiza mediante la seleccion de una serie de nodos
compartidos entre elementos adjacentes, incluyendo los vertices de los elementos. Esto
se debe a que es justamente a traves de estos nodos que se acopla el sistema global para
dar lugar a la solucion unica para la malla.
2.3.2 Generacion de nodos de interpolacion
Conociendo el numero de elementos y su distribucion, es posible generar los nodos de
interpolacion sobre cada elemento. De acuerdo con las secciones anteriores, las ubica-
ciones ideales para estos nodos corresponden justamente a los ceros de las familias de
polinomios ortogonales. Mas aun, como se deben incluir nodos de frontera compartidos
para asegurar las condiciones de continuidad, se prefieren familias como las de Lobatto
sobre las de Chevyshev o Legendre (para el caso unidimensional). Como aun bajo esta
restriccion existen un gran numero de posibles definiciones, en [14] se estudian diferentes
Capıtulo 2. El Metodo de Elementos Espectrales 21
posibilidades y sus consecuencias respectivas. De acuerdo con lo anterior y al resultado
de convergencia espectral obtenido (junto con sus analogos para mas dimensiones), el
caso ideal corresponde a los nodos de interpolacion de Fekete. Estos coinciden justa-
mente con los de Lobatto para el caso 1D y para el caso 2D con dominios cuadrilaterales
(ya que los nodos se obtienen a partir de productos tensoriales de desarrollos provenientes
del caso 1D).
Adicionalmente, en el caso de estudio (las ecuaciones de Navier-Stokes) se cuenta con
dos conjuntos de nodos de interpolacion (en velocidad y en presion), aunque el sistema
correpondiente a la ecuacion diferencial parcial se encuentra proyectado sobre los nodos
de interpolacion de velocidad unicamente. Esto significa que es necesario definir los
nodos de interpolacion para ambos casos, pero solo para los nodos de velocidad es
necesario garantizar completamente la continuidad de la funcion, por razones que se
discutiran en la seccion siguiente. De hecho, es necesario que se satisfaga la ecuacion:
2(NuG)i
NpG
> 1, (2.28)
donde (NuG)i corresponde a los nodos de interpolacion internos, o que no estan sobre la
frontera del dominio completo. De este modo, si se utiliza un nodo de interpolacion de
presion por elemento (i. e. esencialmente se toma la presion promedio del elemento), la
condicion indica que los nodos de interpolacion para velocidad deben ser por lo menos
cuadraticos.
2.3.3 Matriz de conectividad
Una vez se definen los nodos, la matriz de conectividad se construye sencillamente recor-
riendo ordenadamente cada uno de los nodos en cada uno de los elementos, y verificando
si el nodo ya existe en la lista. Esto es, en cada pasada se asigna el numero correspondi-
ente, o se agrega el nuevo nodo. Es de especial interes notar que la identificacion de los
nodos tiene en cuenta que un mismo nodo puede tener coordenadas ligeramente distintas
en distintos elementos debido a errores de precision o calculo, por lo cual es importante
definir una toleracia de identificacion de nodos coincidentes (generalmente una fraccion
del paso mas pequeno entre nodos consecutivos.
Capıtulo 2. El Metodo de Elementos Espectrales 22
2.4 Construccion de la matriz global y el vector del lado
derecho
Para la construccion de la matriz global del problema es necesario primero terminar de
reducir los resultados de las Ecuacion 2.4 y Ecuacion 2.9 a una expresion que dependa
exclusivamente de los nodos de interpolacion. Para ello, recordando que el gradiante de
la funcion de velocidad se puede reexpresar mediante ∇~u =∑Nu
Gj=1(∇φuj )~uj , el resultado
es:
0 =
NuG∑
j=1
~uj ·∫Dφpi∇φ
uj dV (2.29)
0 =
NpG∑
j=1
pj
∮∂D
φui φpj dS − µ
NuG∑
j=1
~uj
∮∂D
φui ~n · ∇φuj dS
+
NpG∑
j=1
pj
∫D∇φui φ
pj dV − µ
NuG∑
j=1
~uj
∫D∇φui · ∇φuj dV (2.30)
donde el ultimo termino corresponde a la matriz de difusion Duij , es decir:
Duij =
∫D∇φui · ∇φuj dV (2.31)
Ahora bien, si se aplican condiciones de frontera de Dirichlet sobre toda la frontera
del dominio, los primeros dos terminos de la ultima ecuacion se vuelven identicamente
0 para las funciones de interpolacion de los nodos internos. Esto quiere decir que el
sistema final se encuentra formado entonces por
0 = µ
NuG∑
j=1
Duij~uj −
NpG∑
j=1
~Ajipj , (2.32)
con ~Aji =∫D∇φ
ui φ
pj dV o, para el caso bidimensional:
~Aji = (Axij , Ayij) =
(∫D
∂φui∂x
φpj dA,
∫D
∂φui∂y
φpj dA
). (2.33)
Capıtulo 2. El Metodo de Elementos Espectrales 23
Reescribiendo esto en forma se sistema lineal, el resultado en entonces:
µDu 0 −ATx
0 µDu −ATy−Ax −Ay 0
·
ux1...
uxNuG
uy1...
uyNuG
p1...
pNpG
= 0 (2.34)
Como las presiones estan presentes en 2(NuG) ecuaciones de este sistema, que adicional-
mente se reducen a 2(NuG)i al implementar las condicionesde frontera, se requiere que
2(NuG)i > Np
G para que el sistema efectivamente tenga solucion. Habiendo definido lo
anterior, es posible proceder a construir las matrices son respecto a las cuales se plantea
numericamente el problema original.
2.4.1 Matrices por elemento
Para la generacion de la matriz global del problema es necesario definir primero cada
una de las matrices correspondientes por cada elemento. En el caso 1D esto corresponde
a las matrices de masa y de difusion (o rigidez) por cada elemento. Respectivamente, se
tienen:
Θij =
∫ 1
−1ψi(ξ)ψj(ξ) dξ Ψij =
∫ 1
−1
dψidξ
dψjdξ
dξ, (2.35)
que se presentan en su forma adimensional ya que el valor de la integral original no
depende de la ubicacion del elemento, y el tamano del mismo se puede incorporar pos-
terirmente mediante las relaciones A(l)ij = 2
hlΨij y B
(l)ij = hl
2 Θij .
Similarmente, para el caso 2D se tienen las matrices de difusion/rigidez y masa, asi
como una matriz nueva: la matriz de adveccion. Segun el tipo de elemento, en este caso
usualmente no es posible llegar a una construccion adimensional ya que la integracion
puede ser sensible a la posicion y la orientacion de los elementos (asi como al tamano).
Las ecuaciones en este caso son:
D(`)ij =
∫∫E`
∇ψ(`)i ·∇ψ
(`)j dxdy M
(`)ij =
∫∫E`
ψ(`)i ψ
(`)j dxdy N
(`)ij =
∫∫E`
ψ(`)i ~u·∇ψ(`)
j dxdy,
(2.36)
respectivamente.
Capıtulo 2. El Metodo de Elementos Espectrales 24
Para su calculo se hace necesario determinar los gradientes de las funciones de interpo-
lacion. Para ello, se utilizan las funciones de interpolacion (ψi(ξ, η)), sus derivadas con
respecto a ξ y a η,(∂ψi(ξ,η)
∂ξ , ∂ψi(ξ,η)∂η
)y tambien el jacobiano correspondiente al cambio
de coordenadas (x, y)↔ (ξ, η), o los terminos de la forma:
∂x
∂ξ,∂x
∂η,∂y
∂ξ,∂y
∂η.
Todo esto hace posible calcular los gradientes de las funciones de interpolacion mediante
el sistema lineal 2× 2 [3]: (∂x∂ξ
∂y∂ξ
∂x∂η
∂y∂η
)∇ψi =
(∂ψi
∂ξ
∂ψi
∂ξ
)(2.37)
Finalmente, para el calculo de la integral se utilizan tipicamente cuadraturas de Gauss
para el tipo de dominio correspondiente.
2.4.2 Matriz de difusion global
Para la construccion de la matriz global basta con sumar los efectos de cada una de las
matrices por elemento. Sin embargo, es importante notar que la matriz original siempre
va a ser singular, ya que las matrices por elemento son, por construccion, singulares.
Aun asi, este problema se puede solucionar facilmente con la remocion de una fila y
una columna del sistema (usualmente las primeras o las ultimas) donde la condicion de
frontera indique un valor conocido o al menos una restriccion que permita deducir su
valor de manera posterior.
Para el caso unidimensional, se puede observar que los unicos nodos compartidos son los
extremos de los intervalos, de manera que se obtienen patrones de esparcidad correspon-
dientes a bloques unidos por sus elementos extremos (como en el caso de la Figura 2.5).
Por su parte, el caso 2D es mas sensible a estas consideraciones, como se observa en al
comparar las implementaciones 2D.
2.4.3 Vector derecho
En el lado derecho se incorporan los terminos adicionales del problema, incluyendo la
funcion de entrada y posibles terminos dependientes del tiempo en casos no estacionarios.
En el caso de la ecuacion de Navier-Stokes, esto corresponde a los terminos derivados
de la presion, las cargas externas y la dependencia en el tiempo. Es importante rescatar
que implementar las condiciones de frontera significa modificar, o bien a la matriz del
problema, o bien a este vector. Esto puede ser dandole un valor nuevo (frontera de
Capıtulo 2. El Metodo de Elementos Espectrales 25
Figura 2.5: Diagrama de esparcidad para la matriz de difusion en 1D
Neumann), o sumando/restando el efecto de los nodos de frontera adjacentes (frontera
de Dirichlet). A modo de ejemplo, para el caso bidimensional con fronteras de Dirichlet
se procede de la siguiente manera si l es un nodo de frontera:
• Sustituir las entradas bi por bi −Dilfl (Incluyo el efecto del nodo
• Cambiar el termino bl por fl
• Igualar las entradas de la fila l y columna l por 0 en la matriz global
• Reajustar el termino Dll a 1.
siendo D la matriz del problema, ~b el vector del lado derecho y f la funcion evaluada en
el nodo (ξl, ηl).
Capıtulo 3
Implementacion en 1D
3.1 Flujo de Couette
En el flujo de Couette generalizado el fluido se encuentra confinado entre placas planas
paralelas infinitas y esta sometido a un gradiente de presion. Las placas se encuentran
separadas por una distancia constante L y el gradiente de presion se presenta en la
direccion del flujo (paralelo a las placas). Adicionalmente, las velocidades de las placas
son U0 y U1 (en direccion x) respectivamente. Todo esto se refleja en la Figura 3.1.
Figura 3.1: Diagrama representativo del flujo de Couette generalizado (Adaptado de[15])
De acuerdo con este planteamiento, se tienen en cuenta las siguientes consideraciones:
• El flujo se presenta unicamente en la direccion x (v = w = 0).
26
Capıtulo 3. Implementacion 1D 27
• El gradiente de presion al que esta sometido el fluido es constante ( ∂p∂x = p).
• El flujo no depende de la coordenada z ( ∂∂z = 0).
• El fluido se encuentra en estado estacionario ( ∂∂t = 0).
• No hay fuerzas externas afectando el flujo (fx = fy = fz = 0).
De aquı, las ecuaciones de continuidad y de Navier-Stokes se reducen a:
∂ρ
∂t+∇ · (ρ~u) = 0 → ∂u
∂x= 0 (3.1)
ρ
(∂~u
∂t+ ~u · ∇~u
)= ρ~f −∇p+ µ∇2~u → 0 = ρu
∂u
∂x= −p+ µ
∂2u
∂y2(3.2)
En este caso, la inexistencia de terminos no lineales proviene de las suposiciones de
flujo unidimensional hechas, y por lo tanto no hace falta verificar la condicion de Stokes
sobre el numero de Reynolds. Adicionalmente, rescatando la relacion con la ecuacion de
difusion, la ecuacion resultante actua como un caso particular del problema de difusion
estable:
kd2f
dx2+ s(x) = 0, (3.3)
donde k = µ, y s(x) = −p, y las condiciones de frontera corresponden a valores conocidos
(tipo Dirichlet):
u(0) = U0 u(L) = U1 (3.4)
Teniendo esto en cuenta, la solucion analıtica corresponde a
u(y) =∆p
2µ`(y2 − Ly) +
U1 − U0
Ly + U0 (3.5)
3.2 Solucion por elementos espectrales
Ahora, de acuerdo con lo desarrollado en el Capıtulo 2, para aplicar el metodo de
elementos espectrales es necesario realizar los siguientes pasos:
• Introduccion de la informacion del problema
• Definicion de los elementos a usar (cantidad NE y distribucion, ası como sus
ordenes NP (i))
– Seleccion de los nodos de interpolacion a usar
– Generacion de la matriz de conectividad
Capıtulo 3. Implementacion 1D 28
• Generacion del sistema lineal del problema
– Generacion de la matriz de difusion
– Generacion del vector b (del lado derecho)
• Solucion del sistema resultante
Como la teorıa detras de cada uno de los mismos se menciono previamente, solo se men-
cionan los desarrollos nuevos cuando sean relevantes. En todo caso, los codigos de las
funciones usadas se presentan en el Apendice A en la seccion correspondiente al modulo
sem1D. En este caso los parametros introducidos son µ = 1, ∇p/` ∈ {−40,−20, 0, 20, 40},L = 2.0, U0 = 0 y U1 = 50. De acuerdo con esto, los elementos a usar se construyen
mediante la separacion en intervalos uniformes del dominio y los nodos de interpolacion
se definen como los puntos de Fekete o ceros de Lobatto. Para esto se utilizo la funcion
genNodes(Ne,Np,xe). Una vez se definen los nodos, se utiliza la matriz de conectivi-
dad para almacenar de manera ordenada la numeracion local y global de los mismos
(genConn(Ne,Np,xint)).
Figura 3.2: Distribucion de los elementos y los nodos de interpolacion correspondi-entes a la malla (2,4,6,5,3,1)
En este caso, la funcion de entrada corresponde a la constante definida por el gradiente
de presion indicado, asi que es necesario calcular tanto la matriz de difusion como la
de masa. Para la generacion de estas matrices, se utilizan las matrices adimensionales
Capıtulo 3. Implementacion 1D 29
definidas anteriormente:
Θij =
∫ 1
−1ψi(ξ)ψj(ξ)dξ Ψij =
∫ 1
−1
dψidξ
dψjdξ
dξ, (3.6)
y se aplica la cuadratura de Lobatto para la construccion de dichas matrices, con lo que
se obtienen los siguientes resultados:
Θij =
Np+1∑p=1
mipmjpwp Ψij =
Np+1∑p=1
dipdjpwp (3.7)
Figura 3.3: Diagrama de esparcidad en la matriz del problema
La construccion se hace por medio de matDiff(Ne,Np,xe,xglob,C,U0,U1,mu,s= lambda
x: -p[it]) y, teniendo esto, basta aplicar un esquema de solucion razonable para el
tipo de matriz obtenida. Como el sistema es pequeno, en este caso se utiliza el solu-
cionador por defecto del modulo scipy.linalg. Dado que los valores para el primer y
ultimo nodo son conocidos, se omiten los valores correspondientes (haciendo la matriz no
singular). La grafica correspondiente se presenta en la Figura 3.4. En la misma se pre-
senta tambien la grafica de la solucion analıtica, donde la diferencia se debe al elemento
lineal usado en uno de los extremos. Debido a esto, es de interes notar como distintos
refinamientos pueden afectar el error percibido, el cual es el objetivo de la siguiente
seccion. De manera puntual, si se sustituye la malla usada por una malla equivalente
con elementos de orden 4, el error se hace nulo (del orden del error de calculo del equipo
correspondiente), como se observa de la Figura 3.5.
Capıtulo 3. Implementacion 1D 30
Figura 3.4: Soluciones obtenidas para el flujo bajo distintos gradientes de presion
Figura 3.5: Soluciones obtenidas con los nuevos nodos
3.3 Comparacion de resultados
Como en este caso la solucion analıtica corresponde a la parabola definida por Ecuacion 3.5,
se puede observar que incluso para un numero bastante reducido de elementos que pueden
tener ordenes bajos la solucion es practicamente exacta. De hecho, como el orden de
esta funcion es cuadratico, distribuciones de elementos cuadraticos alcanzan a capturar
Capıtulo 3. Implementacion 1D 31
NE \NP 1 2 3 4 5 6
1 25.00 6.25 1.19e− 13 2.03e− 13 4.09e− 13 3.34e− 132 25.00 1.96e− 13 2.74e− 13 2.88e− 13 1.17e− 12 3.38e− 133 25.00 5.04e− 13 4.64e− 13 4.69e− 13 1.22e− 12 5.90e− 134 25.00 9.41e− 13 6.86e− 13 6.54e− 13 1.62e− 12 8.17e− 135 25.00 1.40e− 12 9.84e− 12 1.15e− 12 1.99e− 12 8.95e− 136 25.00 1.95e− 12 1.43e− 12 1.53e− 12 2.45e− 12 1.20e− 127 25.00 2.61e− 12 1.97e− 12 1.95e− 12 2.93e− 12 2.29e− 128 25.00 3.50e− 12 2.25e− 12 2.43e− 12 3.36e− 12 2.98e− 129 25.00 4.44e− 12 2.91e− 12 3.09e− 12 4.22e− 12 3.16e− 12
Tabla 3.1: Errores medidos para distintas mallas
relativamente bien esta solucion al utilizar splines cubicas. La Tabla 3.1 presenta los
errores para distintas mallas, refinando tanto el numero de elementos como sus ordenes.
Para casos mas interesantes (en que la funcion objetivo no es polinomial, sino posible-
mente exponencial), es posible rescatar cuales son los refinamientos mas adecuados (e
inclusive su orden) [3]. Mas aun, en terminos de precision, el resultado de una imple-
mentacion con 2 elementos de orden 2 (5 nodos globales) es comparable a una imple-
mentacion de elementos finitos (lineales) de 8 elementos; mientras una con 2 elementos
de orden 4 (9 nodos globales) es comparable a una de 128 elementos lineales [3].
Capıtulo 4
Implementacion en 2D
4.1 Flujo con una cavidad rectangular
Figura 4.1: Diagrama representativo del flujo en la cavidad
En el flujo con una cavidad rectangular, el fluido se encuentra confinado en una region
rectangular de dimensiones L × W donde el movimiento se debe al desplazamiento
transversal de una de las caras. En este sentido, la velocidad de la cara superior es
de U0 y el de las demas interfaces es de 0. De acuerdo con esto, se tienen las siguientes
consideraciones:
• El flujo se presenta unicamente en las direcciones x y y (w = 0).
• El flujo no depende de la coordenada z ( ∂∂z = 0).
• El fluido se encuentra en estado estacionario ( ∂∂t = 0).
32
Capıtulo 4. Implementacion 2D 33
• No hay fuerzas externas afectando el flujo (fx = fy = fz = 0).
De aquı, las ecuaciones de continuidad y de Navier-Stokes se reducen a:
∂ρ
∂t+∇ · (ρ~u) = 0 → ∂u
∂x+∂v
∂y= 0 (4.1)
ρ
(∂~u
∂t+ ~u · ∇~u
)= ρ~f −∇p+ µ∇2~u →
ρ(u∂u∂x + v ∂u∂y
)= − ∂p
∂x + µ(∂2u∂x2
+ ∂2u∂y2
)ρ(u ∂v∂x + v ∂v∂y
)= −∂p
∂v + µ(∂2v∂x2
+ ∂2v∂y2
)(4.2)
Nuevamente se puede ver el parecido con el problema de conveccion-difusion estable,
dado que lo anterior se puede ver como
∂f
∂t+ ~u · ∇f = k∇2f +
s
ρcp, (4.3)
donde ∂f∂t = 0, k = µ
ρ = ν, y scp
= −∂p∂∗ para f = u, ∗ = x y f = v, ∗ = y, y las condiciones
de frontera corresponden a valores conocidos (tipo Dirichlet).
Para que el problema tratado sea efectivamente manejable mediante la aproximacion de
Stokes, es necesario asegurar que se satisfaga la condicion ρ‖~u‖Lµ = Re � 1. Para este
caso, se trabaja con valores de los parametros ρ = 1, U0 = 1, L = 2.4 y µ = 100, dando
como resultado Re = 0.024.
4.2 Solucion por elementos espectrales
Para aplicar el metodo de elementos espectrales, es necesario realizar los siguientes pasos,
los cuales se describienron en el Capıtulo 2:
• Introduccion de la informacion del problema
• Definicion de los elementos a usar (cantidad NE y distribucion, ası como sus
ordenes NP (i))
– Seleccion de los nodos de interpolacion a usar
– Generacion de la matriz de conectividad
• Generacion de la matriz del problema
– Generacion de la matriz de difusion
∗ Calculo de las funciones de interpolacion
Capıtulo 4. Implementacion 2D 34
∗ Calculo de las derivadas de las funciones de interpolacion
∗ Calculo de la funcion de transformacion y sus derivadas
∗ Calculo de los gradientes de las funciones de interpolacion
∗ Calculo del factor de correccion (cambio de base) hs
– Generacion de las matrices de presion
– Generacion del vector b
∗ Implementacion de las condiciones de frontera
• Solucion del sistema resultante
• Grafica de la solucion obtenida
Se define primero el numero de elementos y su distribucion, ası como los ordenes de cada
uno de los mismos. Conociendo el numero de elementos y su distribucion, es posible
generar los nodos correspondientes a los vertices de cada elemento con ayuda de las
funciones del modulo sem2D descrito en el Apendice A. En el caso cuadrilateral, se uti-
lizan los nodos de interpolacion de Lobatto, mientras que en el triangular se usan los de
Fekete. Una vez se definen los nodos con ayuda de las funciones genNodes(Ne,Np,px,py)
y genNodesTri(Ne,m,px,py), nuevamente se utiliza la matriz de conectividad para al-
macenar de manera ordenada la numeracion local y global de los mismos. La funcion
genConn(Ne,Npm,ne,npe,x,y,L,W,U0,h) se encarga de esto en ambos casos al intro-
ducir los valores correspondientes del parametro Npm, correspondiente al Np del caso
cuadrangular y al m del caso triangular.
Pasando a la generacion de la matriz del problema, es necesario definir las matrices
de difusion, masa y adveccion por cada elemento descritas anteriormente. De acuerdo
con lo desarrollado en el Capıtulo 2, estas construcciones radican en la definicion de las
funciones de interpolacion y sus derivadas. Como se indico en el Capıtulo 2, en el caso
cuadrilateral estas integrales se obtienen utilizando la cuadratura de Lobatto sobre cada
una de las dimensiones, usando que las funciones de interpolacion son bilineales y se
escriben de la forma:
(ξ, η) = Li(ξ)Wi(η) (4.4)
donde Li(ξ) y Wi(η) son las funciones de interpolacion (unidimensionales) correspondi-
entes y, por simplicidad, se trabaja sobre el elemento estandar con coordenadas
(−1,−1), (1,−1), (−1, 1) y (1, 1).
Capıtulo 4. Implementacion 2D 35
Figura 4.2: Distribucion de los elementos y los nodos de interpolacion correspondi-entes a la malla con 8 elementos en cada direccion y orden 2 en cada coordenada
aludiendo a un cambio de coordenadas. Por su parte, en el triangulo se trabaja con
funciones descritas como solucion a un sistema de ecuaciones (usando la matriz de Van-
dermonde) sobre el elemento
(0, 0), (1, 0), (0, 1).
Comenzamos con la matriz que define el sistema de ecuaciones, o la matriz de difusion.
Dado que esta depende de los gradientes de las funciones de interpolacion, es necesario
realizar todos los pasos de construccion de los terminos como sigue. Con la expresion
de las funciones de interpolacion como
ψi(ξ, η) =
m∏l 6=j
ξ − ξlξj − ξl
n∏l 6=k
η − ηlηk − ηl
, (4.5)
las derivadas con respecto a ξ y η son entonces:
∂ψ(j,k)(ξ, η)
∂ξ= ψ(j,k)(ξ, η)
m∑l 6=j
1
ξ − ξl=
m∑l 6=j
1
ξj − ξl
m∏p 6=j,l
ξ − ξpξj − ξp
n∏l 6=k
η − ηlηk − ηl
(4.6)
∂ψ(j,k)(ξ, η)
∂η= ψ(j,k)(ξ, η)
m∑l 6=k
1
η − ηl=
n∏l 6=j
ξ − ξlξj − ξl
m∑l 6=k
1
ηk − ηl
m∏p6=k,l
η − ηpηk − ηp
(4.7)
Capıtulo 4. Implementacion 2D 36
Figura 4.3: Malla correspondiente al caso triangular con 8 elementos por direccion yorden 2
De manera similar, para el caso triangular se tiene que
ψi(ξ, η) =Det[Vφ(ξ1, η1, ξ2, η2, . . . , ξ, η, . . . , ξN , ηN )]
Det[Vφ(ξ1, η1, ξ2, η2, . . . , ξi, ηi, . . . , ξN , ηN )](4.8)
y sus derivadas con respecto a ξ y η corresponden a sustituir la ecuacion correspondiente
de los polinomios de proriol por su derivada (los unicos terminos no constantes en toda
la descripcion corresponden a esta columna en la matriz del numerador). Esto es,
∂ψi(ξ, η)
∂ξ=
Det[V (φ1(ξ1, η1), φ2(ξ2, η2), . . . ,∂φi∂ξ (ξ, η), . . . , φN (ξN , ηN ))]
Det[Vφ(ξ1, η1, ξ2, η2, . . . , ξi, ηi, . . . , ξN , ηN )](4.9)
∂ψi(ξ, η)
∂η=
Det[V (φ1(ξ1, η1), φ2(ξ2, η2), . . . ,∂φi∂η (ξ, η), . . . , φN (ξN , ηN ))]
Det[Vφ(ξ1, η1, ξ2, η2, . . . , ξi, ηi, . . . , ξN , ηN )](4.10)
De este modo, la funcion de transformacion de coordenadas corresponde a:
~x =
Np−1∑i=0
~xEi ψi(ξ, η) =
Np−1∑i=0
~xEi ψ(j,k)(ξ, η) =
Np−1∑i=0
~xEi Lj(ξ)Wk(η) (4.11)
Capıtulo 4. Implementacion 2D 37
y por lo tanto sus derivadas son:
∂x
∂ξ=
Np−1∑i=0
xEi∂ψi(ξ, η)
∂ξ
∂x
∂η=
Np−1∑i=0
xEi∂ψi(ξ, η)
∂η
∂y
∂ξ=
Np−1∑i=0
yEi∂ψi(ξ, η)
∂ξ
∂y
∂η=
Np−1∑i=0
yEi∂ψi(ξ, η)
∂η(4.12)
Ya con estos valores, es posible solucionar los gradientes de las funciones solucionando
los sistemas: (∂x∂ξ
∂y∂ξ
∂x∂η
∂y∂η
)∇ψi =
(∂ψi
∂ξ
∂ψi
∂ξ
)(4.13)
De manera que el coeficiente de cambio de coordenadas corresponde a:
Det[J ] =
∣∣∣∣∣∂x∂ξ ∂x∂η
∂y∂ξ
∂y∂η
∣∣∣∣∣ =∂x
∂ξ
∂y
∂η− ∂x
∂η
∂y
∂ξ(4.14)
Ahora bien, como tampoco se conocen los valores de presion, es necesario incorporarlas
tambien como incognitas. Para ello se calculan los vectores:
A(`)i =
∫∫E`
∇ψ(`)i dxdy (4.15)
En las Figuras 4.4, 4.5 y 4.6 se presentan los patrones de esparcidad correspondientes
a los tres tipos de numeracion desarrollados, que se tratan nuevamente al momento de
comparar sus rendimiento mas adelante. Para el caso YX, la unica diferencia esta en el
patron de esparcidad (y el tiempo de solucion) que se presentan en la Figura 4.5
En este caso no es necesario trabajar con las matrices de masa y adveccion pues las sim-
plificaciones hechas (flujo de Stokes) eliminan justamente los terminos correspondientes
a estas. Sin embargo, habiendo calculado las funciones de interpolacion y sus gradientes,
su evaluacion de puede hacer directamente con la cuadratura apropiada.
Para el otro lado de la ecuacion se implementa la funcion de entrada. Para esto se
recorre sobre todos los elementos y se van calculando los valores para la funcion de
manera correspondiente. Estos valores se acomodan al sistema global aprovechando la
matriz de conectividad. Ası mismo, es necesario modificar la matriz global de manera
que se incorporen las condiciones de frontera de Dirichlet. Teniendo ya construidos los
componentes del sistema a resolver, basta aplicar un esquema de solucion razonable para
el tipo de matriz obtenida. En este caso se utiliza el solucionador por defecto del modulo
linalg. Dado que la matriz construida inicialmente es singular, se omiten los valores de
Capıtulo 4. Implementacion 2D 38
Figura 4.4: Diagrama de esparcidad en la matriz del sistema cuadrilateral XY
Figura 4.5: Diagrama de esparcidad en la matriz del sistema para el caso YX
la primera fila y columna - que corresponden a un nodo de frontera del que ya se conoce
la velocidad. Esto permite que la matriz obtenida sea invertible.
Una vez resuelto el sistema, es posible visualizar el resultado obtenido por medio de
graficas para el campo de velocidades, y el de presiones.
Capıtulo 4. Implementacion 2D 39
Figura 4.6: Diagrama de esparcidad en la matriz del sistema triangular
Figura 4.7: Solucion obtenida para el flujo en la cavidad con la malla rectangularconstruida
Por su parte, la solucion triangular no se puede presentar con el respectivo mapa de
color debido a la necesidad de un dominio rectangular para el trazado de los mismos
en Python. En todo caso, las soluciones en velocidad son esencialmente identicas salvo
ligeras desviaciones por los bordes de elemento adicionales. Es importante notar que
hay diferencias en cuanto a las presiones reportadas debido a que se trabaja unicamente
Capıtulo 4. Implementacion 2D 40
Figura 4.8: Solucion obtenida para el campo de presiones en la cavidad con la mallaconstruida
con sus gradientes y por lo tanto se definen unicamente salvo una constante.
Figura 4.9: Solucion obtenida para el flujo en la cavidad con la malla triangular
Capıtulo 4. Implementacion 2D 41
Figura 4.10: Solucion obtenida para el campo de presiones en la cavidad con la mallatriangular
4.3 Analisis de resultados
Al variar la nomenclatura de nodos se observan tiempos de solucion diferentes pero
esencialmente la misma solucion global. Esto sucede debido a que el ancho de banda de la
matriz global del problema depende directamente de la manera en que estan numerados
los nodos. Esto es, si las matrices representan un mismo problema, se tendra que llegar
a la misma solucion siempre y cuando los esquemas de solucion sean igualmente precisos,
pero no necesariamente en el mismo tiempo. Si bien la numeracion externa, o de los
elementos, tiende a ser la misma para distintos casos de solucion, es importante notar
que es la numeracion interna de los nodos la que modifica el aspecto de cada uno de
los bloques correspondientes a las matrices por elemento, de manera que se analiza
especificamente este efecto.
Para evaluar los tiempos que toma a cada uno de los tres esquemas de numeracion
(cuadrilateral con numeracion XY y con numeracion YX y triangular con numeracion
cıclica), se utiliza el caso de estudio descrito en el Capıtulo 5. En esta ocasion, se definen
numeros de elementos y ordenes, de manera que las divisiones coincidan y el numero
de nodos sea el mismo en todos los casos. Estas condiciones se refieren a: 24 divisiones
sobre el eje x (de longitud 2.4), 16 divisiones sobre el eje y (de ancho 1.6), y orden 3 en
cada dimension (casos cuadrilaterales) o cada elemento (caso triangular). Para tomar
en cuenta las variaciones que pueden llegar a haber entre distintas corridas del codigo,
se utilizan 40 sistemas en cada caso.
Capıtulo 4. Implementacion 2D 42
Operacion Tiempo Promedio Desviacion
Definicion de nodos 42.94 0.44Calculo de la matriz 28.57 0.37Solucion del sistema 16.16 0.51
Tiempo Total 87.68 1.08
Tabla 4.1: Tiempos medidos para la numeracion XY
4.3.1 Elementos quadrilaterales con numeracion XY
Figura 4.11: Numeracion en el orden XY
Esta es la numeracion natural de los nodos siguiendo la convencion fisica XY dentro
de cada elemento, como se ilustra en la Figura 4.11. Para este caso, hay varios saltos
en la numeracion a regiones distintas en la malla, lo que se traduce en un patron de
esparcidad mas disperso (Figura 4.12). Para el caso de estudio indicado previamente,
los tiempos requeridos para las tres operaciones se registran en la Tabla 4.1.
4.3.2 Elementos quadrilaterales con numeracion YX
Esta es la numeracion natural de las matrices siguiendo la convencion ij dentro de cada
elemento, como se ilustra en la Figura 4.13. Para este caso, la numeracion tiende a
ser mas uniforme y los saltos se presentan unicamente al cambiar de fila de elementos.
Esto se traduce en franjas mas largas en el patron de esparcidad (Figura 4.14). Para el
caso de estudio indicado previamente, los tiempos requeridos para las tres operaciones
se registran en la Tabla 4.2.
Capıtulo 4. Implementacion 2D 43
Figura 4.12: Patron de esparcidad en el orden XY
Figura 4.13: Numeracion en el orden YX
4.3.3 Elementos triangulares con numeracion cıclica
Esta es una numeracion natural de los nodos triangulares, siguiendo la convencion cıclica
y terminando por los nodos interiores, como se ilustra en la Figura 4.15. Para este caso, el
mayor numero de nodos compartidos resulta en un patron de esparcidad menos ordenado
y se alcanza un ancho de bando mayor en los bloques centrales (Figura 4.16). Para el
Capıtulo 4. Implementacion 2D 44
Operacion Tiempo Promedio Desviacion
Definicion de nodos 43.79 0.37Calculo de la matriz 28.54 0.30Solucion del sistema 15.59 0.44
Tiempo Total 87.92 0.89
Tabla 4.2: Tiempos medidos para la numeracion YX
Figura 4.14: Patron de esparcidad en el orden YX
Operacion Tiempo Promedio Desviacion
Definicion de nodos 57.14 0.22Calculo de la matriz 14.11 0.03Solucion del sistema 17.69 0.40
Tiempo Total 88.93 0.60
Tabla 4.3: Tiempos medidos para la numeracion triangular
caso de estudio indicado previamente, los tiempos requeridos para las tres operaciones
se registran en la Tabla 4.3.
4.3.4 Comparacion de los resultados
De acuerdo con lo que se aprecia en cada una de las tablas, si bien las distintas numera-
ciones tienen ventajes significativas en uno u otro componente, los tiempos promedios
que les toma el calculo de la sulcion completa es aproximadamente el mismo. Pun-
tualmente, los nodos mas faciles de generar y graficar corresponden a las numeraciones
Capıtulo 4. Implementacion 2D 45
Figura 4.15: Numeracion en el orden cıclico
Figura 4.16: Patron de esparcidad en la numeracion cıclica
XY y YX, ya que estas se pueden obtener rapidamente mediante el uso de la funcion
meshgrid( , ). Por su parte, los elementos triangulares se numeran manualmente y por
lo tanto requieren un tiempo ligeramente mayor (aproximadamente 15 segundos mayor
en este caso). Mas aun, el numero de elementos para el caso triangular es el doble que
en los otros casos, contribuyendo tambien a esta diferencia.
En cuanto a la generacion de la matriz del problema, la situacion se reversa: el tiempo
Capıtulo 4. Implementacion 2D 46
para la numeracion triangular es casi la mitad del tiempo requerido para los casos XY
y YX. En las numeraciones XY y YX se hacen necesarias una serie de ciclios anidados
para recorrer cada dimension de cada componente (nodos de interpolacion del elemento,
nodos de la cuadratura) y adicionalmente el uso de multiples condicionales por la forma
de la funcion de interpolacion, ralentizando significativamente la velocidad de solucion.
Por su parte, el caso triangular presenta funciones precalculadas explicitamente, como lo
son los polinomios de Proriol y sus derivadas respectivas. Asi mismo, aun si el numero
de elementos es el doble, la cantidad de operaciones requerida en cada uno es menor.
Por su parte, la solucion de los sistemas es el proceso que tiene menor variacion entre
los tres. Sin embargo, es posible apreciar que la numeracion YX toma un tiempo que
alcanza a ser notablemente (i. e. estadısticamente significativo) menor que el de la
numeracion XY y, a su vez, este ultimo al de la numeracion triangular. Como en este
caso el tamano de los sistemas sigue siendo relativamente pequeno, estos resultados ya
significativos podrian indicar la aparicion de diferencias mucho mayores para tamanos
mas grandes.
Adicionalmente, es importante comparar los resultados obtenidos con los resultados re-
portados en literatura o por otras implementaciones de metodos similares. En particular
se tiene buena consistencia con los resultados de [16, 17] y de la implementacion de [3].
Figura 4.17: Visualizacion reologica para el flujo en la cavidad (Tomado de [17])
Capıtulo 4. Implementacion 2D 47
Figura 4.18: Solucion obtenida para el flujo en la cavidad en elementos finitos (Im-plementacion de [3])
Capıtulo 5
Mejoramiento del codigo
Dado que uno de los factores que motivaron la realizacion del proyecto era justamente
la necesidad de mejorar los tiempos de solucion requeridos, para la parte final de este
proyecto se trabajo con estrategias para acelerar el codigo. Puntualmente se estudiaron
algunas de las alternativas existentes para el lenguaje Python y la manera en que se
realizo esta implementacion. En este sentido, se trabaja sobre la optimizacion manual y
sobre la compilacion en tiempo de ejecucion, justo a tiempo o compilacion just-in-time
(JIT por sus siglas en ingles).
5.1 Optimizacion manual
La primera estrategia de optimizacion para cualquier programa corresponde a la reestruc-
turacion del codigo. Al minimizar la cantidad de operaciones que requiere hacer el pro-
grama, tambien se esta reduciendo su tiempo de ejecucion. De manera puntual, cuando
existen operaciones que se requieren hacer multiples veces o que pueden llegar a ser cos-
tosas en tiempo, es posible tener en su lugar un diccionario de valores a utilizar segun
los parametros que se introduzcan. Esto reduce el tiempo requerido para la funcion al
equivalente de una busqueda con los parametros usados.
Si bien esto limita severamente los tamanos y los ordenes de los elementos a usar,
tıpicamente se tiene en cuenta cuales son los tamanos y valores maximos para su uti-
lizacion practica. De este modo, es justamente para estos valores que se encuentran al
extremo superior en complejidad que se presenta el mayor ahorro en tiempo.
Para el caso del codigo implementado, los ejemplos mas claros de lo anterior se encuen-
tran en la evaluacion de las familias de polinomios ortogonales y en la generacion de
las matrices por elemento unidimensionales. A modo de ejemplo, se rescata primero la
48
Capıtulo 5. Mejoramiento del codigo 49
expresion desarrollada en el Apendice B correspondiente a los polinomios de Proriol:
Pkl(ξ, η) = Lk
(2ξ
1− η− 1
)(1− η)kJ
(2k+1,0)l (2η − 1). (5.1)
Si bien los polinomios de Legendre y de Jacobi se pueden calcular explıcitamente, es-
tas expresiones requieren la realizacion de multiples multiplicaciones iteradas, o pueden
requerir de XXX. Esto es, requieren un tiempo significativo para su calculo. Adicional-
mente, el termino 1 − η en el denominador de la primera expresion indica que no es
posible evaluar esa formulacion cuando η = 1 (note que la expresion (1 − η)k cancela
el denominador resultante). Por el contrario, si se calculan previamente las expresiones
explicitas de los polinomios a usar (como se observa en el Apendice B), se puede usar la
evaluacion siguiente
def proriol(k,l,xi,eta):
#=================================================
# Evalua los polinomios de Proriol usando las
# formas precalculadas
#
# Admite polinomios de orden hasta 3: k+l < 4
#=================================================
if(k==0 and l==0):
val = 1
elif(k==1 and l==0):
val = 2*xi+eta -1
elif(k==0 and l==1):
val = 3*eta -1
elif(k==2 and l==0):
val = 6*xi**2+6*xi*eta+eta**2 -6*xi-2*eta +1
elif(k==1 and l==1):
val = (2*xi+eta -1)*(5*eta -1)
elif(k==0 and l==2):
val = 10*eta**2 -8*eta +1
elif(k==3 and l==0):
val = (2*xi+eta -1)*(10*xi**2+10*xi*eta+eta**2 -10*xi-2*eta +1)
elif(k==2 and l==1):
val = (6*xi**2+6*xi*eta+eta**2 -6*xi-2*eta +1)*(7*eta-1)
elif(k==1 and l==2):
val = (2*xi+eta -1)*(21*eta**2 -12*eta +1)
elif(k==0 and l==3):
val = 35*eta**3 -45*eta**2 +15*eta -1
else:
raise NameError(’Orden invalido’)
return val
Aquı se encuentran calculados los polinomis de Proriol de orden hasta 3, debido a que
la implementacion hecha maneja puntos de Fekete de orden hasta 3. De hecho, por la
definicion de estos puntos es necesario hacer algo similar para su ubicacion al interior
del triangulo (en las fronteras coinciden con los ceros de Lobatto) [10]. En todo caso,
no se evaluan los polinomios de legendre y jacobi para ser operados entre si, sino que se
usa la expresion que resulta de evaluar la formulacion anterior.
Capıtulo 5. Mejoramiento del codigo 50
De manera similar, en el caso unidimensional es posible simplificar la evaluacion de
las matrices por elemento. En lugar de usar la expresion formal como integrales de
gradientes o derivadas:
D(`)ij =
∫E`
d
dxψ(`)i ·
d
dxψ(`)j dx, (5.2)
es posible tener un catalogo de las matrices de difusion adimensionales precalculadas.
def edm(N=6):
#=======================================
# spectral element diffusion matrix for
# an Nth-order polynomial expansion.
#
# N in 1 - 6
#=======================================
if(N==1):
elm_dm = np.array([[0.5, -0.5],[-0.5, 0.5]])
elif(N==2):
elm_dm = np.array([
[1.16666666666667, -1.33333333333333, 0.16666666666667],
[-1.33333333333333, 2.66666666666667, -1.33333333333333],
[0.16666666666667, -1.33333333333333, 1.16666666666667]])
elif(N==3):
elm_dm = np.array([
[2.16666666666667, -2.43920915260403, 0.35587581927070, -0.08333333333333],
[-2.43920915260403, 4.16666666666667, -2.08333333333333, 0.35587581927070],
[0.35587581927070, -2.08333333333333, 4.16666666666667, -2.43920915260404],
[-0.08333333333333, 0.35587581927070, -2.43920915260404, 2.16666666666667]])
elif(N==4):
elm_dm = np.array([
[3.50000000000000, -3.91288507544030, 0.53333333333333, -0.17044825789303,
0.05000000000000],
[-3.91288507544030, 6.35185185185185, -2.90370370370371, 0.63518518518519,
-0.17044825789303],
[0.53333333333333, -2.90370370370371, 4.74074074074074, -2.90370370370371,
0.53333333333333],
[-0.17044825789303, 0.63518518518519, -2.90370370370371, 6.35185185185185,
-3.91288507544030],
[0.05000000000000, -0.17044825789303, 0.53333333333333, -3.91288507544030,
3.50000000000000]])
elif(N==5):
elm_dm = np.array([
[5.16666666666647, -5.75534978755293, 0.75291274743628, -0.23286955119427,
0.10197325797781, -0.03333333333336],
[-5.75534978755293, 9.12668826478755, -3.98085223985198, 0.83085223985201,
-0.32331173521247, 0.10197325797781],
[0.75291274743628, -3.98085223985198, 6.03997840187932, -3.41002159812136,
0.83085223985201, -0.23286955119427],
[-0.23286955119427, 0.83085223985201, -3.41002159812136, 6.03997840187932,
-3.98085223985198, 0.75291274743628],
[0.10197325797781, -0.32331173521247, 0.83085223985201, -3.98085223985198,
9.12668826478755, -5.75534978755293],
[-0.03333333333336, 0.10197325797781, -0.23286955119427, 0.75291274743628,
-5.75534978755293, 5.16666666666647]])
else: # Incorpora los casos en que N >= 6
elm_dm = np.array([
[7.16666666666692, -7.96655757431697, 1.01647769632621, -0.30476190476184,
0.13291684274811, -0.06855125047193, 0.02380952380950],
[-7.96655757431697, 12.47251984118633, -5.29457208031436, 1.06606416109113,
Capıtulo 5. Mejoramiento del codigo 51
-0.40971363397094, 0.20081053679675, -0.06855125047193],
[1.01647769632621, -5.29457208031436, 7.74748015881332, -4.17463558966276,
0.98204660606043, -0.40971363397094, 0.13291684274811],
[-0.30476190476184, 1.06606416109113, -4.17463558966276, 6.82666666666694,
-4.17463558966276, 1.06606416109113, -0.30476190476184],
[0.13291684274811, -0.40971363397094, 0.98204660606043, -4.17463558966276,
7.74748015881332, -5.29457208031436, 1.01647769632621],
[-0.06855125047193, 0.20081053679675, -0.40971363397094, 1.06606416109113,
-5.29457208031436, 12.47251984118632, -7.96655757431697],
[0.02380952380950, -0.06855125047193, 0.13291684274811, -0.30476190476184,
1.01647769632621, -7.96655757431697, 7.16666666666691]])
return elm_dm
Nuevamente, es importante notar que el limite en este caso corresponde a N ≤ 6. Otros
ejemplos de este fenomeno son la evaluacion de los ceros de Lobatto con sus respectivos
pesos de cuadratura, la evaluacion de las matrices adimensionales de masa para el caso
1D, y la evaluacion de los puntos de cuadratura triangular.
5.2 Lenguajes interpretados y lenguajes compilados
Entrando concretamente a hablar de Python, una de las propiedades que caracteriza al
lenguaje es su caracter interpretado. Esto quiere decir que posee una mayor flexibilidad
como lenguaje, tanto a travez de distintas plataformas, como en el manejo de las vari-
ables. Esto quiere decir que en lugar de asignar a una variable un tipo estatico o fijo,
es posible asignar tipos dinamicos de manera que no sea necesario inicializar la vari-
able junto con su tipo e inclusive ir variando estos tipos a lo largo de la ejecucion [18].
Sin embargo, este dinamismo hace que la ejecucion como un todo sea menos eficiente,
tanto en tiempo como en memoria. Esto es, al existir la necesidad de un interprete
(ubicado localmente sobre la maquina) que vaya traduciendo el codigo o al uso de una
representacion intermedia, la ejecucion sera mas lenta.
En contraparte, los lenguajes compilados tienden a estar disenados para optimizar los
tiempos de ejecucion, a costa de portabilidad. Esto es, al ser mas rıgidos tanto tienden a
funcionar solo en la version especıfica de su plataforma en que se realiza la compilacion.
Su funcionamiento radica en la compilacion del codigo fuente a un ejecutable antes de
utilizar formalmente el codigo. Su mayor velocidad corresponde a que las instrucciones
en esta version compilada son mas cercanas a codigo de maquina nativo que se puede
procesar directamente por la CPU.
Considerando ambas versiones, uno de los desarrollos actuales mas relevantes corre-
sponde a la posibilidad de implementaciones mixtas. Esto es, la utilizacion de un
lenguaje interpretado mediante la compilacion previa de las partes crıticas del codigo.
Una de las estrategias mas populares para esto es la compilacion just in time.
Capıtulo 5. Mejoramiento del codigo 52
5.3 Compilacion Justo a Tiempo (JIT)
La compilacion justo a tiempo, tambien conocida como compilacion en tiempo de eje-
cucion, se define como un proceso de traduccion dinamica que no se efectua antes de
la ejecucion de un programa (como en el caso de la compilacion usual), sino durante la
misma [18]. Tipicamente consiste en la traduccion de partes del codigo a lenguaje de
maquina nativo. Esto quiere decir que el procesador puede recibir estas instrucciones y
ejecutarlas directamente. Como se indico anteriormente, su principal funcion es la de
combinar la velocidad de ejecucion de los lenguajes compilados con la flexibilidad de los
interpretados.
Para el caso de Python existe la librerıa numba, que permite compilarel codigo en lenguaje
de maquina de bajo nivel (LLVM IR), que se puede ejecutar mucho mas rapidamente.
Esta libreria permite cumplir con esta tarea de distintas maneras, segun el nivel de
especificacion que se introduzca. Esto quiere decir que el resultado final puede depender
de que tanta informacion adicional se provee a la hora de compilar.
Una de las primeras formas de utilizar el paquete radica en la utilizacion de un decorador
sobre las funciones a compilar. De manera concreta, se incluye la linea @jit antes de
las definiciones de las funciones correspondientes. Esto permite que automaticamente
se detecte el tipo de los parametros introducidos. Sin embargo, como es necesario que
el programa detecte estos tipos para realizar la compilacion, esto puede llegar a resultar
costoso cuando se trabaja con multiples parametros o salidas.
Para solucionar lo anterior, es posible especificar al programa cuales son los tipos de los
parametros, con lo cual se usan una serie de aliases (por ejemplo b1 para un booleano,
f4 para un flotante de 32 bits o i1[:] para un arreglo unidimensional de enteros) segun
el tipo de variable.
Alternativamente es posible generar nuevas funciones a partir de las predefinidas con
ayuda de la funcion autojit(). En este caso, a las nuevas funciones se les puede
asignar un nuevo nombre. La sintaxis correspondiente es entonces:
numba_genNodes = autojit()(sem2D.genNodes)
numba_genNodes.func_name = "numba_genNodes"
numba_genConn = autojit()(sem2D.genConn)
numba_genConn.func_name = "numba_genConn"
numba_matDiff = autojit()(sem2D.matDiff)
numba_matDiff.func_name = "numba_matDiff"
Al aplicar estas estrategias al codigo utilizado sobre la implementacion 2D con nu-
meracion XY, con tamanos de 12×8 y ordenes 3 y 2 respectivamente, el resultado es un
Capıtulo 5. Mejoramiento del codigo 53
tiempo mayor al original. El tiempo de ejecucion promedio sin JIT es de 7.295 segundos,
mientras que al aplicar JIT el tiempo aumenta a 12.014 segundos en promedio. Como
esto se puede deber a que el tiempo de compilacion representa una porcion significativa
del tiempo en este caso, se repite el ejercicio con un problema mas grande. Esto es, se
trabaja con una malla de 24 × 16 con elementos de orden 4. En este caso, el resultado
fue una mejorıa significativa en el tiempo de ejecucion. Esto es, se pasa de un promedio
de 365.6 segundos a un promedio de 335.3 segundos. Si bien este ya es un resultado
positivo, es probable que al seguir aumentando el tamano o la complejidad de los prob-
lemas trabajados, el beneficio que resulta de la compilacion se pueda apreciar todavia
mas claramente.
Capıtulo 6
Conclusiones
De acuerdo con lo observado desde el ambito teorico, los metodos de elementos espec-
trales no son mucho mas complicados que los espectrales o los de elementos finitos. En
particular, se pudo verificar que el metodo comparte las bondades de sus antecesores
como la posibilidad de trabajar en subdominios definidos de distintas manera, ası como
la convergencia espectral. Mas aun, fue posible comparar el rendimiento de distintos
tipos de numeraciones de los nodos para obtener diferencias notables en las distintas
partes, pero un tiempo similar en la solucion global del sistema.
En relacion con los objetivos planteados para el proyecto, la implementacion obtenida es
satisfactoria desde el ambito pedagogico pues permite trabajar con los casos mas basicos
de la ecuacion de trabajo y arroja resultados aceptables. Mas aun, los ejemplos rescatan
su alto potencial de mejorar la ejecucion de un programa, siendo comparable a metodos
de elementos finitos con muchos mas elementos, y reduciendo el error resultante expo-
nencialmente. Si bien la aceleracion JIT no se satisfactoria para estos casos pequenos,
serıa necesario evaluar casos mas complejos antes de descartar esta alternativa.
Si bien el resultado es una serie de modulos y una infraestructura que permite trabajar
comodamente con el metodo en el caso lineal, queda pendiente extender el mismo a casos
mas generales. Puntualmente, hasta el momento faltarıa extender el solucionador a casos
mas generales en los cuales no se forcen las simplificaciones indicadas en el Capıtulo 2.
6.1 Comentarios finales
Se obtuvieron resultados consistentes con lo esperado en cuanto al rendimiento de los
metodos analizados. En el caso 1D se observa el efecto de ir refinando sucesivamente la
malla, y en 2D se rescata un mejor rendimiento (en cuanto a la precision de la solucion)
54
Capıtulo 6. Conclusiones 55
cuando se va refinando la malla y para las numeraciones XY y YX debido a la frontera
diagonal entre elementos que altera levemente el resultado esperado. Cabe mencionar
tambien que unicamente se trabajo con geometrias sencillas y condiciones de frontera de
Dirichlet sin la inclusion de los terminos no lineales, por lo que serıa de interes continuar
observando como trabaja el metodo en estas otras configuraciones.
Apendice A
Funciones Utilizadas
A.1 Implementacion 1D
En este apartado se presentan las funciones utilizadas que se implementaron en el modulosem1D.
import numpy as np
#=================================================
# Funciones traducidas y adaptadas de FSELIB
# http://dehesa.freeshell.org/FSELIB/
#=================================================
def lobatto(i=6):
#=================================================
# Zeros of the ith-degree Lobatto polynomial
#
# This table contains values for i = 1, 2, ..., 6
# The default value is i=6
#=================================================
if(i>6):
print(’Data is not available; Will take i=6’)
i=6
Z = np.zeros(i)
if(i==1):
Z[0] = 0.0
elif(i==2):
Z[0] = -1.0/np.sqrt(5.0)
Z[1] = -Z[0]
elif(i==3):
Z[0] = -np.sqrt(3.0/7.0)
Z[1] = 0.0
Z[2] = -Z[0]
56
Appendix A. Funciones Utilizadas 57
elif(i==4):
Z[0] = -0.76505532392946
Z[1] = -0.28523151648064
Z[2] = -Z[1]
Z[3] = -Z[0]
elif(i==5):
Z[0] = -0.83022389627857
Z[1] = -0.46884879347071
Z[2] = 0.0
Z[3] = -Z[1]
Z[4] = -Z[0]
elif(i==6):
Z[0] = -0.87174014850961
Z[1] = -0.59170018143314
Z[2] = -0.20929921790248
Z[3] = -Z[2]
Z[4] = -Z[1]
Z[5] = -Z[0]
return Z
def emm(N=6):
#================================================
# dimensionless element mass matrix for
# Nth-order polynomial expansion
#
# values are given for: N in 1 - 6
#================================================
if(N==1):
elm_mm = np.array([
[2/3, 1/3],
[1/3, 2/3]])
elif(N==2):
elm_mm = np.array([
[0.26666666666667, 0.13333333333333, -0.06666666666667],
[0.13333333333333, 1.06666666666667, 0.13333333333333],
[-0.06666666666667, 0.13333333333333, 0.26666666666667]])
elif(N==3):
elm_mm = np.array([
[0.14285714285714, 0.05323971374999, -0.05323971374999, 0.02380952380952],
[0.05323971375000, 0.71428571428571, 0.11904761904762, -0.05323971374999],
[-0.05323971374999, 0.11904761904762, 0.71428571428571, 0.05323971375000],
[0.02380952380952, -0.05323971374999, 0.05323971375000, 0.14285714285714]])
elif(N==4):
elm_mm = np.array([
[0.08888888888889, 0.02592592592592, -0.02962962962963, 0.02592592592593,
-0.01111111111111],
[0.02592592592592, 0.48395061728395, 0.06913580246913, -0.06049382716049,
0.02592592592593],
[-0.02962962962963, 0.06913580246913, 0.63209876543211, 0.06913580246913,
-0.02962962962963],
[0.02592592592593, -0.06049382716049, 0.06913580246913, 0.48395061728395,
0.02592592592592],
[-0.01111111111111, 0.02592592592593, -0.02962962962963, 0.02592592592592,
Appendix A. Funciones Utilizadas 58
0.08888888888889]])
elif(N==5):
elm_mm = np.array([
[0.06060606060606, 0.01444043443670, -0.01748448154180, 0.01748448154179,
-0.01444043443670, 0.00606060606061],
[0.01444043443670, 0.34406814208894, 0.04165977904505, -0.04165977904505,
0.03440681420889, -0.01444043443670],
[-0.01748448154180, 0.04165977904505, 0.50441670639590, 0.05044167063958,
-0.04165977904505, 0.01748448154179],
[0.01748448154179, -0.04165977904505, 0.05044167063958, 0.50441670639590,
0.04165977904505, -0.01748448154180],
[-0.01444043443670, 0.03440681420889, -0.04165977904505, 0.04165977904505,
0.34406814208894, 0.01444043443670],
[0.00606060606061, -0.01444043443670, 0.01748448154179, -0.01748448154180,
0.01444043443670, 0.06060606060606]])
else: # Incorpora los casos en que N >= 6
elm_mm = np.array([
[0.04395604395604, 0.00883182542984, -0.01102962762764, 0.01172161172161,
-0.01102962762764, 0.00883182542984, -0.00366300366300],
[0.00883182542984, 0.25553173602605, 0.02659340659341, -0.02826184137547,
0.02659340659341, -0.02129431133550, 0.00883182542984],
[-0.01102962762764, 0.02659340659341, 0.39853419803987, 0.03529480840844,
-0.03321118316999, 0.02659340659341, -0.01102962762764],
[0.01172161172161, -0.02826184137547, 0.03529480840844, 0.45010989010988,
0.03529480840844, -0.02826184137547, 0.01172161172161],
[-0.01102962762764, 0.02659340659341, -0.03321118316999, 0.03529480840844,
0.39853419803987, 0.02659340659341, -0.01102962762764],
[0.00883182542984, -0.02129431133550, 0.02659340659341, -0.02826184137547,
0.02659340659341, 0.25553173602605, 0.00883182542984],
[-0.00366300366300, 0.00883182542984, -0.01102962762764, 0.01172161172161,
-0.01102962762764, 0.00883182542984, 0.04395604395604]])
return elm_mm
def edm(N=6):
#=======================================
# spectral element diffusion matrix for
# an Nth-order polynomial expansion.
#
# N in 1 - 6
#=======================================
if(N==1):
elm_dm = np.array([[0.5, -0.5],[-0.5, 0.5]])
elif(N==2):
elm_dm = np.array([
[1.16666666666667, -1.33333333333333, 0.16666666666667],
[-1.33333333333333, 2.66666666666667, -1.33333333333333],
[0.16666666666667, -1.33333333333333, 1.16666666666667]])
elif(N==3):
elm_dm = np.array([
[2.16666666666667, -2.43920915260403, 0.35587581927070, -0.08333333333333],
[-2.43920915260403, 4.16666666666667, -2.08333333333333, 0.35587581927070],
[0.35587581927070, -2.08333333333333, 4.16666666666667, -2.43920915260404],
[-0.08333333333333, 0.35587581927070, -2.43920915260404, 2.16666666666667]])
Appendix A. Funciones Utilizadas 59
elif(N==4):
elm_dm = np.array([
[3.50000000000000, -3.91288507544030, 0.53333333333333, -0.17044825789303,
0.05000000000000],
[-3.91288507544030, 6.35185185185185, -2.90370370370371, 0.63518518518519,
-0.17044825789303],
[0.53333333333333, -2.90370370370371, 4.74074074074074, -2.90370370370371,
0.53333333333333],
[-0.17044825789303, 0.63518518518519, -2.90370370370371, 6.35185185185185,
-3.91288507544030],
[0.05000000000000, -0.17044825789303, 0.53333333333333, -3.91288507544030,
3.50000000000000]])
elif(N==5):
elm_dm = np.array([
[5.16666666666647, -5.75534978755293, 0.75291274743628, -0.23286955119427,
0.10197325797781, -0.03333333333336],
[-5.75534978755293, 9.12668826478755, -3.98085223985198, 0.83085223985201,
-0.32331173521247, 0.10197325797781],
[0.75291274743628, -3.98085223985198, 6.03997840187932, -3.41002159812136,
0.83085223985201, -0.23286955119427],
[-0.23286955119427, 0.83085223985201, -3.41002159812136, 6.03997840187932,
-3.98085223985198, 0.75291274743628],
[0.10197325797781, -0.32331173521247, 0.83085223985201, -3.98085223985198,
9.12668826478755, -5.75534978755293],
[-0.03333333333336, 0.10197325797781, -0.23286955119427, 0.75291274743628,
-5.75534978755293, 5.16666666666647]])
else: # Incorpora los casos en que N >= 6
elm_dm = np.array([
[7.16666666666692, -7.96655757431697, 1.01647769632621, -0.30476190476184,
0.13291684274811, -0.06855125047193, 0.02380952380950],
[-7.96655757431697, 12.47251984118633, -5.29457208031436, 1.06606416109113,
-0.40971363397094, 0.20081053679675, -0.06855125047193],
[1.01647769632621, -5.29457208031436, 7.74748015881332, -4.17463558966276,
0.98204660606043, -0.40971363397094, 0.13291684274811],
[-0.30476190476184, 1.06606416109113, -4.17463558966276, 6.82666666666694,
-4.17463558966276, 1.06606416109113, -0.30476190476184],
[0.13291684274811, -0.40971363397094, 0.98204660606043, -4.17463558966276,
7.74748015881332, -5.29457208031436, 1.01647769632621],
[-0.06855125047193, 0.20081053679675, -0.40971363397094, 1.06606416109113,
-5.29457208031436, 12.47251984118632, -7.96655757431697],
[0.02380952380950, -0.06855125047193, 0.13291684274811, -0.30476190476184,
1.01647769632621, -7.96655757431697, 7.16666666666691]])
return elm_dm
#=================================================
# Funciones nuevas implementadas
#=================================================
def genNodes(Ne,Np,xe):
#=================================================
# Genera los nodos de interpolacion segun el
# numero de elementos y sus ordenes. Esta es la
# numeracion local de los nodos: (l,i)
#
# Ne = Np.size
# max(Np) < 6
#=================================================
Appendix A. Funciones Utilizadas 60
if(Ne != Np.size):
raise NameError(’La cantidad de elementos no coincide con el orden’)
xint = np.zeros((Ne,max(Np)+1))
for l in range(Ne):
mid = 0.5 * (xe[l+1]+xe[l])
dis = 0.5 * (xe[l+1]-xe[l])
xint[l,0] = xe[l]
vals = lobatto(Np[l]-1)
xint[l,1:Np[l]] = mid + vals*dis
xint[l,Np[l]] = xe[l+1]
return xint
def genConn(Ne,Np,xint):
#=================================================
# Genera los vectores de numeracion global y la
# matriz de conectividad
#
# max(Np) < 6
#=================================================
xglob = np.zeros(np.sum(Np)+1)
C = np.zeros((Ne,max(Np)+1),int)
# Contador Global
cont = 0
for l in range(Ne):
C[l,0:Np[l]+1] = np.arange(cont,cont+Np[l]+1)
xglob[cont:cont+Np[l]+1] = xint[l,0:Np[l]+1]
cont+=Np[l]
return xglob, C
def matDiff(Ne,Np,xe,xglob,C,U0,U1,mu=1,s=lambda x: 0):
#=================================================
# Genera la matriz de difusion/rigidez y el vector
# del lado derecho del sistema sujeto a condicio-
# nes de Dirichlet en ambos extremos
#
# max(Np) < 6
#=================================================
Ng = xglob.size
Mat_dif = np.zeros((Ng,Ng))
vec_b = np.zeros(Ng)
s = np.vectorize(s)
for l in range(Ne):
N = Np[l]
h = xe[l+1]-xe[l]
elm_mm = 0.5*h*emm(N)
elm_dm = 2.0*edm(N)/h
Mat_dif[C[l,0]:C[l,N]+1,C[l,0]:C[l,N]+1] += elm_dm
vec_b[C[l,0:N+1]] += np.dot(elm_mm,s(xglob[C[l,0:N+1]]))/mu
# Implementa las condiciones de frontera de Dirichlet
Appendix A. Funciones Utilizadas 61
# Extremo derecho
# los valores de N, h y elm_dm ya corresponden a los del ultimo nodo
vec_b[C[Ne-1,0:N+1]] -= elm_dm[0:N+1,N]*U1
# Extremo izquierdo
N = Np[0]
h = xe[1]-xe[0]
elm_dm = 2.0*edm(Np[0])/h
vec_b[C[0,0:N+1]] -= elm_dm[0:N+1,0]*U0
return Mat_dif, vec_b
A.2 Implementacion 2D
En este apartado se presentan las funciones utilizadas, y que se implementaron en el
modulo sem2D.
import numpy as np # Ofrece funciones para operaciones basicas con arreglos
import scipy.linalg as lin # Ofrece funciones para operaciones de algebra lineal
#=================================================
# Funciones traducidas y adaptadas de FSELIB
# http://dehesa.freeshell.org/FSELIB/
#=================================================
def lobatto(i=6):
#=================================================
# Zeros of the ith-degree Lobatto polynomial
#
# This table contains values for i = 1, 2, ..., 6
# The default value is i=6
#=================================================
if(i>6):
print(’Data is not available; Will take i=6’)
i=6
Z = np.zeros(i)
if(i==1):
Z[0] = 0.0
elif(i==2):
Z[0] = -1.0/np.sqrt(5.0)
Z[1] = -Z[0]
elif(i==3):
Z[0] = -np.sqrt(3.0/7.0)
Z[1] = 0.0
Z[2] = -Z[0]
elif(i==4):
Z[0] = -0.76505532392946
Z[1] = -0.28523151648064
Appendix A. Funciones Utilizadas 62
Z[2] = -Z[1]
Z[3] = -Z[0]
elif(i==5):
Z[0] = -0.83022389627857
Z[1] = -0.46884879347071
Z[2] = 0.0
Z[3] = -Z[1]
Z[4] = -Z[0]
elif(i==6):
Z[0] = -0.87174014850961
Z[1] = -0.59170018143314
Z[2] = -0.20929921790248
Z[3] = -Z[2]
Z[4] = -Z[1]
Z[5] = -Z[0]
return Z
def qlobatto(i=6,r=’b’):
#=================================================
# Zeros of the completed ith-degree Lobatto
# polynomial, and corresponding weights for the
# Lobatto integration quadrature
#
# This table contains values for i = 1, 2, ..., 6
# The default value is i=6
#=================================================
if(i>6):
print(’Data is not available; Will take i=6’)
i=6
Z = np.zeros(i+2)
W = np.zeros(i+2)
Z[0] = -1.0
Z[-1] = -Z[0]
W[0] = 2.0/((i+1)*(i+2))
W[-1] = W[0]
if(i==1):
Z[1] = 0.0
W[1] = 4.0/3.0
elif(i==2):
Z[1] = -1.0/np.sqrt(5.0)
Z[2] = -Z[1]
W[1] = 5.0/6.0
W[2] = W[1]
elif(i==3):
Z[1] = -np.sqrt(3.0/7.0)
Z[2] = 0.0
Z[3] = -Z[1]
W[1] = 49.0/90.0
W[2] = 32.0/45.0
W[3] = W[1]
elif(i==4):
Appendix A. Funciones Utilizadas 63
Z[1] = -0.76505532392946
Z[2] = -0.28523151648064
Z[3] = -Z[2]
Z[4] = -Z[1]
W[1] = 0.37847495629785
W[2] = 0.55485837703549
W[3] = W[2]
W[4] = W[1]
elif(i==5):
Z[1] = -0.83022389627857
Z[2] = -0.46884879347071
Z[3] = 0.0
Z[4] = -Z[2]
Z[5] = -Z[1]
W[1] = 0.27682604736157
W[2] = 0.43174538120986
W[3] = 0.48761904761905
W[4] = W[2]
W[5] = W[1]
elif(i==6):
Z[1] = - 0.87174014850961
Z[2] = - 0.59170018143314
Z[3] = - 0.20929921790248
Z[4] = -Z[3]
Z[5] = -Z[2]
Z[6] = -Z[1]
W[1] = 0.21070422714350
W[2] = 0.34112269248350
W[3] = 0.41245879465870
W[4] = W[3]
W[5] = W[2]
W[6] = W[1]
if(r==’z’):
return Z
elif(r==’w’):
return W
else:
return Z, W
def gaussTri(m):
#================================================
# Abscissas (xi, eta) and weights (w)
# for Gaussian integration over a flat triangle
# in the xi-eta plane
#
# Integration is performed with respect
# to the triangle barycentric coordinates
#
# SYMBOLS:
# -------
#
# m: order of the quadrature
# choose from 1,3,4,6,7,9,12,13
# Default value is 7
#================================================
#------------------------
Appendix A. Funciones Utilizadas 64
# Checks for valid values
#------------------------
if((m != 1) and (m != 3) and (m != 4) and (m != 6) and (m != 7)
and (m != 9) and (m != 12) and (m != 13)):
m = 7
if(m==1):
xi = np.array([1.0/3.0])
eta = np.array([1.0/3.0])
w = np.array([1.0])
elif(m==3):
xi = np.array([1.0/6.0, 2.0/3.0, 1.0/6.0])
eta = np.array([1.0/6.0, 1.0/6.0, 2.0/3.0])
w = np.array([1.0/3.0, 1.0/3.0, 1.0/3.0])
elif(m==4):
xi = np.array([1.0/3.0, 1.0/5.0, 3.0/5.0, 1.0/5.0])
eta = np.array([1.0/3.0, 1.0/5.0, 1.0/5.0, 3.0/5.0])
w = np.array([-27.0/48.0, 25.0/48.0, 25.0/48.0, 25.0/48.0])
elif(m==6):
al = 0.816847572980459
be = 0.445948490915965
ga = 0.108103018168070
de = 0.091576213509771
o1 = 0.109951743655322
o2 = 0.223381589678011
xi = np.array([de, al, de, be, ga, be])
eta = np.array([de, de, al, be, be, ga])
w = np.array([o1, o1, o1, o2, o2, o2])
elif(m==7):
al = 0.797426958353087
be = 0.470142064105115
ga = 0.059715871789770
de = 0.101286507323456
o1 = 0.125939180544827
o2 = 0.132394152788506
xi = np.array([de, al, de, be, ga, be, 1.0/3.0])
eta = np.array([de, de, al, be, be, ga, 1.0/3.0])
w = np.array([o1, o1, o1, o2, o2, o2, 0.225])
elif(m==9):
al = 0.124949503233232
qa = 0.165409927389841
rh = 0.797112651860071
de = 0.437525248383384
ru = 0.037477420750088
o1 = 0.205950504760887
o2 = 0.063691414286223
xi = np.array([de, al, de, qa, ru, rh, qa, ru, rh])
eta = np.array([de, de, al, ru, qa, qa, rh, rh, ru])
w = np.array([o1, o1, o1, o2, o2, o2, o2, o2, o2])
elif(m==12):
al = 0.873821971016996
be = 0.249286745170910
ga = 0.501426509658179
de = 0.063089014491502
rh = 0.636502499121399
Appendix A. Funciones Utilizadas 65
qa = 0.310352451033785
ru = 0.053145049844816
o1 = 0.050844906370207
o2 = 0.116786275726379
o3 = 0.082851075618374
xi = np.array([de, al, de, be, ga, be, qa, ru, rh, qa, ru, rh])
eta = np.array([de, de, al, be, be, ga, ru, qa, qa, rh, rh, ru])
w = np.array([o1, o1, o1, o2, o2, o2, o3, o3, o3, o3, o3, o3])
elif(m==13):
al = 0.479308067841923
be = 0.065130102902216
ga = 0.869739794195568
de = 0.260345966079038
rh = 0.638444188569809
qa = 0.312865496004875
ru = 0.048690315425316
o1 = 0.175615257433204
o2 = 0.053347235608839
o3 = 0.077113760890257
o4 =-0.149570044467670
xi = np.array([de, al, de, be, ga, be, qa, ru, rh, qa, ru, rh, 1.0/3.0])
eta = np.array([de, de, al, be, be, ga, ru, qa, qa, rh, rh, ru, 1.0/3.0])
w = np.array([o1, o1, o1, o2, o2, o2, o3, o3, o3, o3, o3, o3, o4])
return xi, eta, w
#=================================================
# Funciones nuevas implementadas
#=================================================
def proriol(k,l,xi,eta):
#=================================================
# Evalua los polinomios de Proriol usando las
# formas precalculadas
#
# Admite polinomios de orden hasta 3: k+l < 4
#=================================================
if(k==0 and l==0):
val = 1
elif(k==1 and l==0):
val = 2*xi+eta -1
elif(k==0 and l==1):
val = 3*eta -1
elif(k==2 and l==0):
val = 6*xi**2+6*xi*eta+eta**2 -6*xi-2*eta +1
elif(k==1 and l==1):
val = (2*xi+eta -1)*(5*eta -1)
elif(k==0 and l==2):
val = 10*eta**2 -8*eta +1
elif(k==3 and l==0):
val = (2*xi+eta -1)*(10*xi**2+10*xi*eta+eta**2 -10*xi-2*eta +1)
elif(k==2 and l==1):
val = (6*xi**2+6*xi*eta+eta**2 -6*xi-2*eta +1)*(7*eta-1)
elif(k==1 and l==2):
val = (2*xi+eta -1)*(21*eta**2 -12*eta +1)
elif(k==0 and l==3):
val = 35*eta**3 -45*eta**2 +15*eta -1
else:
raise NameError(’La cantidad de elementos no coincide con el orden’)
Appendix A. Funciones Utilizadas 66
return val
def dproriol(k,l,xi,eta,var=’xi’):
#=================================================
# Evalua las derivadas de los polinomios de
# Proriol usando las formas precalculadas
#
# Admite polinomios de orden hasta 3: k+l < 4
#=================================================
if(var==’xi’):
if(k==0 and l==0):
val = 0
elif(k==1 and l==0):
val = 2
elif(k==0 and l==1):
val = 0
elif(k==2 and l==0):
val = 12*xi+6*eta-6
elif(k==1 and l==1):
val = 2*(5*eta -1)
elif(k==0 and l==2):
val = 0
elif(k==3 and l==0):
val = 2*(10*xi**2+10*xi*eta+eta**2-10*xi-2*eta+1)+(2*xi+eta-1)*(20*xi+10*eta-10)
elif(k==2 and l==1):
val = (12*xi+6*eta-6)*(7*eta-1)
elif(k==1 and l==2):
val = 2*(21*eta**2 -12*eta +1)
elif(k==0 and l==3):
val = 0
else:
raise NameError(’La cantidad de elementos no coincide con el orden’)
elif(var==’eta’):
if(k==0 and l==0):
val = 0
elif(k==1 and l==0):
val = 1
elif(k==0 and l==1):
val = 3
elif(k==2 and l==0):
val = 6*xi+2*eta-2
elif(k==1 and l==1):
val = (5*eta -1)+(2*xi+eta -1)*5
elif(k==0 and l==2):
val = 20*eta-8
elif(k==3 and l==0):
val = (10*xi**2+10*xi*eta+eta**2-10*xi-2*eta+1)+(2*xi+eta-1)*(10*xi+2*eta-2)
elif(k==2 and l==1):
val = (6*xi+2*eta-2)*(7*eta-1)+(6*xi**2+6*xi*eta+eta**2 -6*xi-2*eta +1)*7
elif(k==1 and l==2):
val = (21*eta**2 -12*eta +1)+(2*xi+eta -1)*(42*eta-12)
elif(k==0 and l==3):
val = 105*eta**2-90*eta +15
else:
raise NameError(’La cantidad de elementos no coincide con el orden’)
else:
raise NameError(’Variable de derivacion invalida’)
return val
def genVDM(m):
Appendix A. Funciones Utilizadas 67
#=================================================
# Evalua la matriz de Vandermonde generalizada, su
# determinante y la matriz de cofactores
#
# Admite polinomios de orden hasta 3: k+l < 4
#=================================================
# Recupera las posiciones estandar de los nodos
npe = (m+1)*(m+2)/2
distr = 0.5+0.5*lobatto(m-1)
xist = np.zeros(npe)
etast = np.zeros(npe)
xist[0:3*m] = np.concatenate([[0],distr,[1],distr[::-1],np.zeros(m)])
etast[0:3*m] = np.concatenate([np.zeros(m+1),distr,[1],distr[::-1]])
if(m==3):
xist[9] = 1./3.
etast[9] = 1./3.
# Inicializa las matrices requeridas para el calculo
Mat_VDM = np.zeros([npe,npe])
Mat_Cof = np.zeros([npe,npe])
Mat_Min = np.zeros([npe-1,npe-1])
prind = np.array([[0,1,0,2,1,0,3,2,1,0],
[0,0,1,0,1,2,0,1,2,3]])
# Construye la matriz de Vandermonde generalizada
for i in range(npe):
for j in range(npe):
k = prind[0,i]
l = prind[1,i]
Mat_VDM[i,j] = proriol(k,l,xist[j],etast[j])
Det_VDM = lin.det(Mat_VDM)
for i in range(npe):
for j in range(npe):
Temp = np.delete(Mat_VDM,i,0)
Mat_Min = np.delete(Temp,j,1)
Mat_Cof[i,j] = (-1)**(i+j)*np.linalg.det(Mat_Min)
return Mat_VDM, Det_VDM, Mat_Cof
def genNodes(Ne,Np,px,py,ordn=’xy’):
#=================================================
# Genera los nodos de interpolacion segun el
# numero de elementos y sus ordenes. Esta es la
# numeracion local de los nodos: (l,i)
#
# Ne = Np.size
# max(Np) < 6
#=================================================
ne = Ne[0]*Ne[1] # Recupera el numero de elementos
npe = (Np[0]+1)*(Np[1]+1) # Recupera el numero de nodos por elemento
x = np.zeros([ne,npe]) # Coordenadas x por elemento
y = np.zeros([ne,npe]) # Coordenadas y por elemento
# Genera los nodos de interpolacion de Lobatto
dx = qlobatto(Np[0]-1,’z’)
dy = qlobatto(Np[1]-1,’z’)
Appendix A. Funciones Utilizadas 68
for l in range(ne):
cx = l % Ne[0]
cy = l / Ne[0]
midx = 0.5 * (px[cx+1]+px[cx])
disx = 0.5 * (px[cx+1]-px[cx])
midy = 0.5 * (py[cy+1]+py[cy])
disy = 0.5 * (py[cy+1]-py[cy])
pxe = midx+disx*dx
pye = midy+disy*dy
(xv,yv) = np.meshgrid(pxe,pye,indexing=ordn)
x[l,:] = xv.reshape(npe)
y[l,:] = yv.reshape(npe)
return x, y, ne, npe
def genNodesTri(Ne,m,px,py):
#=================================================
# Genera los nodos de interpolacion segun el
# numero de elementos y sus ordenes para una malla
# triangular. Esta es la numeracion local de los
# nodos: (l,i)
#
# m < 4
#=================================================
ne = 2*Ne[0]*Ne[1] # Recupera el numero de elementos
npe = (m+1)*(m+2)/2 # Este es el numero de nodos por elemento
x = np.zeros([ne,npe]) # Coordenadas x por elemento
y = np.zeros([ne,npe]) # Coordenadas y por elemento
# Genera los nodos de interpolacion de Lobatto
distr = lobatto(m-1)
for l in range(ne/2): # Desarrolla dos elementos por iteracion
cx = l % Ne[0]
cy = l / Ne[0]
pxe = 0.5 * ((px[cx+1]+px[cx])+(px[cx+1]-px[cx])*distr)
pye = 0.5 * ((py[cy+1]+py[cy])+(py[cy+1]-py[cy])*distr)
# Elemento inferior
x[2*l,0:3*m] = np.concatenate([[px[cx]],pxe,[px[cx+1]],pxe[::-1],
px[cx]*np.ones(m)])
y[2*l,0:3*m] = np.concatenate([py[cy]*np.ones(m+1),
pye,[py[cy+1]],pye[::-1]])
if(m==3):
x[2*l,9] = (2.*px[cx]+px[cx+1])/3.
y[2*l,9] = (2.*py[cy]+py[cy+1])/3.
# Elemento superior
x[2*l+1,0:3*m] = np.concatenate([[px[cx+1]],pxe[::-1],[px[cx]],pxe,
px[cx+1]*np.ones(m)])
y[2*l+1,0:3*m] = np.concatenate([[py[cy]],pye,py[cy+1]*np.ones(m+1),
pye[::-1]])
if(m==3):
x[2*l+1,9] = (2.*px[cx+1]+px[cx])/3.
y[2*l+1,9] = (2.*py[cy+1]+py[cy])/3.
return x, y, ne, npe
Appendix A. Funciones Utilizadas 69
def genConn(Ne,Npm,ne,npe,x,y,L,W,U0,h,tipo=’quad’):
#=================================================
# Genera los vectores de numeracion global, la
# matriz de conectividad y el vector de frontera
#
# max(Np) < 6 (quad) o m < 4 (tri)
#=================================================
# Calcula el numero de nodos globales para definir el tamano de las matrices
if(tipo == ’quad’):
ng = ne*npe - ((Ne[0]-1)*(Npm[1]+1)+(Ne[1]-1)*(Npm[0]+1)
+(Ne[0]-1)*(Ne[1]-1)*(sum(Npm)+1))
elif(tipo == ’tri’):
ng = ne*npe - ((ne/2+Ne[0]+Ne[1]-2)*(Npm+1)+(Ne[0]-1)*(Ne[1]-1)*(2*Npm+1))
coords = np.zeros([ng,2]) # Almacena las coordenadas los nodos sin redundancia
C = np.zeros((ne,npe),int) # Matriz de conectividad
gfl = np.zeros([ng,3]) # Indicador de nodos de frontera [indicador, vel. x, vel. y]
# Se introduce manualmente el primer nodo
coords[0,0] = x[0,0]
coords[0,1] = y[0,0]
# C[0,0] = 0 Esta condicion ya se tiene de la inicializacion de C
gfl[0,0] = 1 # Indica un nodo de frontera (el valor de la velocidad es de [0,0])
cont = 1 # Contador global
tol = h*1e-6 # Tolerancia para identificacion de nodos iguales
for l in range(ne):
for k in range(npe):
existe = False
for n in range(cont):
if(np.abs(coords[n,0]-x[l,k])+np.abs(coords[n,1]-y[l,k]) < tol):
existe = True
C[l,k] = n # El nodo (l,m) corresponde al nodo global n
if(not existe): # Registra el nodo si no existe todavia
coords[cont,0] = x[l,k]
coords[cont,1] = y[l,k]
C[l,k] = cont
# Identifica los nodos de frontera y actualiza el indicador
if (L/2.-np.abs(x[l,k]) < tol or W/2.-np.abs(y[l,k]) < tol):
gfl[cont,0] = 1
# Si se encuentra en la frontera superior actualiza la velocidad x
if(W/2.-y[l,k] < tol):
gfl[cont,1] = U0
cont += 1
return coords, C, gfl, ng
def matDiff(Ne,Np,ne,npe,ng,x,y,C,gfl,mu=1):
#=================================================
# Genera la matriz de difusion/rigidez y el vector
# del lado derecho del sistema sujeto a condicio-
# nes de Dirichlet
#
# max(Np) < 6
#=================================================
# Recupera los nodos de interpolacion de Lobatto
dx = qlobatto(Np[0]-1,’z’)
dy = qlobatto(Np[1]-1,’z’)
Appendix A. Funciones Utilizadas 70
(xi,wx) = qlobatto(Np[0],’b’) # Utiliza un orden mayor para tener exactitud
(eta,wy) = qlobatto(Np[1],’b’) # Utiliza un orden mayor para tener exactitud
NQ = (Np[0]+2)*(Np[1]+2) # Numero de nodos a usar en la cuadratura
(ix,iy) = np.meshgrid(range(Np[0]+2),range(Np[1]+2),indexing=’xy’)
M_ind = np.array([ix.reshape(NQ),iy.reshape(NQ)]).T # Indices para la cuadratura
Mat_dif = np.zeros([2*ng+ne,2*ng+ne]) # Inicializa la matriz de difusion global
for l in range(ne):
elm_dm = np.zeros([npe,npe]) # Inicializa la matriz de difusion elemental
vecD = np.zeros([npe,2])
# Realiza la cuadratura de Gauss
for nq in M_ind:
psi = np.ones(npe) # Almacena las funciones de interpolacion
dpsixi = np.zeros(npe) # Almacena las derivadas con respecto a xi
dpsieta = np.zeros(npe) # Almacena las derivadas con respecto a eta
grpsi = np.zeros([npe,2]) # Almacena los gradientes de las funciones
dxdxi = 0.
dxdeta = 0.
dydxi = 0.
dydeta = 0.
for i in range(npe): #Realiza los calculos sobre cada elemento
divx = i % (Np[0]+1)
divy = i / (Np[0]+1)
# Calcula las funciones de interpolacion
fx = 1
for ind in range(Np[0]+1):
if(ind != divx):
fx *= (xi[nq[0]]-dx[ind])/(dx[divx]-dx[ind])
# print fx,
fy = 1
for ind in range(Np[1]+1):
if(ind != divy):
fy *= (eta[nq[1]]-dy[ind])/(dy[divy]-dy[ind])
psi[i] = fx*fy
# print fy, psi[i]
# Calcula las derivadas con respecto a las dos variables
for ind in range(Np[0]+1):
if(ind != divx):
prod = 1
for ind2 in range(Np[0]+1):
if(ind2 != divx and ind2 != ind):
prod *= (xi[nq[0]]-dx[ind2])/(dx[divx]-dx[ind2])
dpsixi[i] += 1./(dx[divx]-dx[ind])*prod
dpsixi[i] *= fy
for ind in range(Np[1]+1):
if(ind != divy):
prod = 1
for ind2 in range(Np[1]+1):
if(ind2 != divy and ind2 != ind):
prod *= (eta[nq[1]]-dy[ind2])/(dy[divy]-dy[ind2])
dpsieta[i] += 1./(dy[divy]-dy[ind])*prod
dpsieta[i] *= fx
# print dpsixi[i], dpsieta[i]
# Actualiza los valores de las derivadas de la funcion de transformacion
Appendix A. Funciones Utilizadas 71
dxdxi += x[l,i]*dpsixi[i]
dxdeta += x[l,i]*dpsieta[i]
dydxi += y[l,i]*dpsixi[i]
dydeta += y[l,i]*dpsieta[i]
# print dxdxi,dxdeta,dydxi,dydeta
for i in range(npe):
# Calcula el gradiente para cada funcion de interpolacion
grpsi[i,:] = lin.solve(np.array([[dxdxi,dydxi],[dxdeta,dydeta]]),
np.array([dpsixi[i],dpsieta[i]]))
# Calcula el factor de correccion
hs = np.abs(dxdxi*dydeta-dxdeta*dydxi)
# Construye la matriz de difusion elemental
for i in range(npe):
for j in range(npe):
elm_dm[i,j] += np.dot(grpsi[i,:],grpsi[j,:])*(hs*wx[nq[0]]*wy[nq[1]])
# Construye los vectores D
vecD[i,:] += grpsi[i,:]*(hs*wx[nq[0]]*wy[nq[1]])
# Actualiza la matriz de difusion global
Mat_dif[np.meshgrid(C[l,:],C[l,:],indexing=’ij’)] += mu*elm_dm
Mat_dif[np.meshgrid(ng+C[l,:],ng+C[l,:],indexing=’ij’)] += mu*elm_dm
# Extensiones
Mat_dif[C[l,:],2*ng+l] -= vecD[:,0] #incorpora Dx en el bloque B
Mat_dif[ng+C[l,:],2*ng+l] -= vecD[:,1] #incorpora Dy en el bloque B
Mat_dif[2*ng+l,C[l,:]] -= vecD[:,0] #incorpora Dx en el bloque C
Mat_dif[2*ng+l,ng+C[l,:]] -= vecD[:,1] #incorpora Dy en el bloque C
# Construye el vector del lado derecho
vec_b = np.zeros(2*ng+ne)
# Implementa las condiciones de frontera
for ind in range(ng):
if(gfl[ind,0]==1):
# Ajusta las entradas al lado derecho
vec_b -= Mat_dif[:,ind]*gfl[ind,1] + Mat_dif[:,ng+ind]*gfl[ind,2]
# Ajusta el valor de la entrada en b
vec_b[ind] = gfl[ind,1] # Coor. x
vec_b[ng+ind] = gfl[ind,2] # Coor. y
# Ajusta la matriz del problema
Mat_dif[:,ind] = np.zeros(2*ng+ne)
Mat_dif[:,ng+ind] = np.zeros(2*ng+ne)
Mat_dif[ind,:] = np.zeros(2*ng+ne)
Mat_dif[ng+ind,:] = np.zeros(2*ng+ne)
Mat_dif[ind,ind] = 1.
Mat_dif[ng+ind,ng+ind] = 1.
return Mat_dif, vec_b
def matDiffTri(Ne,m,ne,npe,ng,x,y,C,gfl,mu=1):
#=================================================
# Genera la matriz de difusion/rigidez y el vector
# del lado derecho del sistema sujeto a condicio-
# nes de Dirichlet para el caso triangular
#
# m < 4
#=================================================
Appendix A. Funciones Utilizadas 72
# Define los nodos a usar en la cuadratura
NQ = 7 # Numero de nodos a usar en la cuadratura (1,3,4,6,7,9,12,13)
(xiq, etaq, wq) = gaussTri(NQ)
(Mat_VDM, Det_VDM, Mat_Cof) = genVDM(m)
prind = np.array([[0,1,0,2,1,0,3,2,1,0],
[0,0,1,0,1,2,0,1,2,3]])
Mat_dif = np.zeros([2*ng+ne,2*ng+ne]) # Inicializa la matriz de difusion global
for ell in range(ne):
elm_dm = np.zeros([npe,npe]) # Inicializa la matriz de difusion elemental
vecD = np.zeros([npe,2])
# Realiza la cuadratura de Gauss
for nq in range(NQ):
psi = np.ones(npe) # Almacena las funciones de interpolacion
dpsixi = np.zeros(npe) # Almacena las derivadas con respecto a xi
dpsieta = np.zeros(npe) # Almacena las derivadas con respecto a eta
grpsi = np.zeros([npe,2]) # Almacena los gradientes de las funciones
dxdxi = 0.
dxdeta = 0.
dydxi = 0.
dydeta = 0.
for i in range(npe): #Realiza los calculos sobre cada elemento
# Calcula las funciones de interpolacion
vect = np.zeros(npe)
for j in range(npe):
k = prind[0,j]
l = prind[1,j]
vect[j] = proriol(k,l,xiq[nq],etaq[nq])
psi[i] = np.dot(vect,Mat_Cof[:,i])/Det_VDM
# Calcula las derivadas con respecto a las dos variables
vect = np.zeros(npe)
for j in range(npe):
k = prind[0,j]
l = prind[1,j]
vect[j] = dproriol(k,l,xiq[nq],etaq[nq],’xi’)
dpsixi[i] = np.dot(vect,Mat_Cof[:,i])/Det_VDM
vect = np.zeros(npe)
for j in range(npe):
k = prind[0,j]
l = prind[1,j]
vect[j] = dproriol(k,l,xiq[nq],etaq[nq],’eta’)
dpsieta[i] = np.dot(vect,Mat_Cof[:,i])/Det_VDM
# print dpsixi[i], dpsieta[i]
# Actualiza los valores de las derivadas de la funcion de transformacion
dxdxi += x[ell,i]*dpsixi[i]
dxdeta += x[ell,i]*dpsieta[i]
dydxi += y[ell,i]*dpsixi[i]
dydeta += y[ell,i]*dpsieta[i]
# print dxdxi,dxdeta,dydxi,dydeta
for i in range(npe):
# Calcula el gradiente para cada funcion de interpolacion
grpsi[i,:] = lin.solve(np.array([[dxdxi,dydxi],[dxdeta,dydeta]]),
np.array([dpsixi[i],dpsieta[i]]))
# Calcula el factor de correccion
hs = np.abs(dxdxi*dydeta-dxdeta*dydxi)
Appendix A. Funciones Utilizadas 73
# Construye la matriz de difusion elemental
for i in range(npe):
for j in range(npe):
elm_dm[i,j] += np.dot(grpsi[i,:],grpsi[j,:])*(0.5*hs*wq[nq])
# Construye los vectores D
vecD[i,:] += grpsi[i,:]*(0.5*hs*wq[nq])
# Actualiza la matriz de difusion global
Mat_dif[np.meshgrid(C[ell,:],C[ell,:],indexing=’ij’)] += mu*elm_dm
Mat_dif[np.meshgrid(ng+C[ell,:],ng+C[ell,:],indexing=’ij’)] += mu*elm_dm
# Extensiones
Mat_dif[C[ell,:],2*ng+ell] -= vecD[:,0] #incorpora Dx en el bloque B
Mat_dif[ng+C[ell,:],2*ng+ell] -= vecD[:,1] #incorpora Dy en el bloque B
Mat_dif[2*ng+ell,C[ell,:]] -= vecD[:,0] #incorpora Dx en el bloque C
Mat_dif[2*ng+ell,ng+C[ell,:]] -= vecD[:,1] #incorpora Dy en el bloque C
# Construye el vector del lado derecho
vec_b = np.zeros(2*ng+ne)
# Implementa las condiciones de frontera
for ind in range(ng):
if(gfl[ind,0]==1):
# Ajusta las entradas al lado derecho
vec_b -= Mat_dif[:,ind]*gfl[ind,1] + Mat_dif[:,ng+ind]*gfl[ind,2]
# Ajusta el valor de la entrada en b
vec_b[ind] = gfl[ind,1] # Coor. x
vec_b[ng+ind] = gfl[ind,2] # Coor. y
# Ajusta la matriz del problema
Mat_dif[:,ind] = np.zeros(2*ng+ne)
Mat_dif[:,ng+ind] = np.zeros(2*ng+ne)
Mat_dif[ind,:] = np.zeros(2*ng+ne)
Mat_dif[ng+ind,:] = np.zeros(2*ng+ne)
Mat_dif[ind,ind] = 1.
Mat_dif[ng+ind,ng+ind] = 1.
return Mat_dif, vec_b
Apendice B
Familias de Funciones
Ortogonales
De acuerdo con lo indicado previamente, este apendice presenta una breve descripcion
de las familias de polinomios mas usadas tanto en 1D como en 2D (para dominios trian-
gulares). Adicional a esto, se presentan los primeros miembros y las formulas generales
para estos polinomios.
B.1 Familias de Funciones 1D
En el caso de funciones 1D se mencionan especıficamente las familias de polinomios de
Legendre, Lobatto, Chevyshev (primer y segundo tipo) y Jacobi.
B.1.1 Polinomios de Legendre
Los polinomios de Legendre se definen naturalmente como las soluciones de las ecua-
ciones diferenciales
d
dξ
[(1− ξ2) d
dξLn(ξ)
]+ n(n+ 1)Ln(ξ) = 0, (B.1)
con n ∈ N y son comunes en el contexto de la ecuacion de Laplace. La ortogonalidad de
estos polinomios viene dada por el hecho de que tambien son el resultado de aplicar el
proceso de Gram-Schmidt sobre la base canonica 1, x, x2, . . . con una funcion de pesos
w(ξ) = 1 [19]. De acuerdo con lo anterior,∫ 1
−1Li(t)Lj(t) dt =
2
2i+ 1δij . (B.2)
74
Appendix B. Familias de Funciones Ortogonales 75
Esta propiedad implica en particular que∫ 1−1 Li(t) dt = 0 (usando j = 0). Asi mismo,
dada la procedencia de estas funciones se tiene que |Li(t)| ≤ 1 ∀t ∈ [−1, 1].
Polinomios de Legendre
L0(ξ) = 1L1(ξ) = ξL2(ξ) = 1
2(3ξ2 − 1)L3(ξ) = 1
2(5ξ2 − 3)ξL4(ξ) = 1
8(35ξ4 − 30ξ2 + 3)L5(ξ) = 1
8(63ξ4 − 70ξ2 + 15)ξL6(ξ) = 1
16(231ξ6 − 315ξ4 + 105ξ2 − 5)L7(ξ) = 1
16(429ξ6 − 693ξ4 + 315ξ2 − 35)ξ. . .
Li(ξ) = 12ii!
di
dξi(ξ2 − 1)i
Tabla B.1: Primeros miembros de la familia de polinomios de Legendre (Adaptadode [3])
Para el calculo de los polinomios de interpolacion en 2D, particularmente de los miembros
de orden 3 de la familia de Proriol son de interes los polinomios de Legendre de la forma
Lk
(2ξ1−η − 1
). A continuacion se presentan los polinomios usados:
L0
(2ξ
1− η− 1
)= 1
L1
(2ξ
1− η− 1
)=
2ξ
1− η− 1 =
2ξ + η − 1
1− η
L2
(2ξ
1− η− 1
)=
1
2(3
(2ξ
1− η− 1
)2
− 1) =6ξ2 + 6ξη + η2 − 6ξ − 2η + 1
(1− η)2
L3
(2ξ
1− η− 1
)=
1
2(5
(2ξ
1− η− 1
)2
− 3)
(2ξ
1− η− 1
)=
(2ξ + η − 1)(10ξ2 + 10ξη + η2 − 10ξ − 2η + 1)
(1− η)3(B.3)
B.1.2 Polinomios de Lobatto
Estos polinomios se pueden obtener a partir de los de Legendre mediante la relacion
Loi(ξ) = L′i+1(ξ). Es por esto que muchas de las propiedades que presentan los poli-
nomios de Legendre son heredadas por los polinomios de Lobatto. Sin embargo, en este
caso la funcion de pesos deja de ser la funcion unitaria y pasa a ser w(ξ) = 1 − ξ2. La
ortogonalidad se sigue entonces mediante la integracion por partes, la definicion dada
Appendix B. Familias de Funciones Ortogonales 76
por la Ecuacion B.1, y la ortogonalidad de los polinomios de Legendre:
< Loi, Loj >w =
∫ 1
−1Loi(t)Loj(t)(1− t2) dt
=
∫ 1
−1L′i+1(t)L
′j+1(t)(1− t2) dt
=[L′i+1(t)(1− t2)Lj+1(t)
]1−1 −
∫ 1
−1Lj+1(t)
(L′i+1(t)(1− t2)
)′dt
= 0 + (i+ 1)(i+ 2)
∫ 1
−1Li+1(t)Lj+1(t)(1− t2) dt
=2(i+ 1)(i+ 2)
2i+ 3δij . (B.4)
Particularmente, se observa nuevamente que∫ 1−1 Loi(t)(1− t
2)dt = 0 (usando j = 0).
Polinomios de Lobatto
Lo0(ξ) = 1Lo1(ξ) = 3ξLo2(ξ) = 3
2(5ξ2 − 1)Lo3(ξ) = 5
2(7ξ2 − 3)ξLo4(ξ) = 15
8 (21ξ4 − 14ξ2 + 1)Lo5(ξ) = 1
8(693ξ4 − 630ξ2 + 105)ξLo6(ξ) = 1
16(3003ξ6 − 3465ξ4 + 945ξ2 − 35). . .
Loi(ξ) = 12i+1(i+1)!
di+2
dξi+2 (ξ2 − 1)i+1
Tabla B.2: Primeros miembros de la familia de polinomios de Lobatto (Adaptado de[3])
B.1.3 Polinomios de Chevyshev
Los polinomios de Chevyshev (del primer tipo) surgen a partir de la solucion de las
ecuaciones diferenciales
(1− ξ2) d2
dξ2Tn(ξ)− ξ d
dξTn(ξ) + n2Tn(ξ) = 0, (B.5)
con n ∈ N y son especialmente valiosos en la interpolacion de funciones al minimizar el
error de interpolacion en funciones continuas (bajo la norma del supremo, o ‖·‖∞). Esto
es, aun con funciones como las de Runge no son susceptibles al fenomeno de oscilacion
y acaban por converger uniformemente a la funcion a interpolar [3]. En particular, se
observa que los polinomios 2−(n−1)Tn(t) tienen la mınima norma posible entre todos
los posibles polinomios de su mismo orden en el intervalo [−1, 1] [19]. En este caso, la
Appendix B. Familias de Funciones Ortogonales 77
funcion de pesos corresponde a w(ξ) = 1√1−ξ2
de acuerdo con su relacion a las funciones
trigonometricas.
Polinomios de Chevyshev
T0(ξ) = 1T1(ξ) = ξT2(ξ) = 2ξ2 − 1T3(ξ) = 4ξ3 − 3ξT4(ξ) = 8ξ4 − 8ξ2 + 1T5(ξ) = 16ξ5 − 20ξ3 + 5ξ. . .Ti(ξ) = cos(i arccos ξ) = 2i−1ξi − i2i−3ξi−2 + . . .
Tabla B.3: Primeros miembros de la familia de polinomios de Chevyshev (Adaptadode [3])
B.1.4 Polinomios de Chevyshev del segundo tipo
Para los polinomios del segundo tipo la situacion es similar. Los polinomios son la
solucion de la ecuacion diferencial
(1− ξ2) d2
dξ2Tn(ξ)− 3ξ
d
dξTn(ξ) + n(n+ 2)Tn(ξ) = 0, (B.6)
con n ∈ N, y pesos w(ξ) =√
1− ξ2.
Polinomios de Chevyshev del segundo tipo
T0(ξ) = 1T1(ξ) = 2ξT2(ξ) = 4ξ2 − 1T3(ξ) = 8ξ3 − 4ξT4(ξ) = 16ξ4 − 12ξ2 + 1T5(ξ) = 32ξ5 − 32ξ3 + 6ξ. . .
Ti(ξ) = sin((i+1) arccos ξ)sin(arccos ξ)
Tabla B.4: Primeros miembros de la familia de polinomios de Chevyshev del segundotipo
B.1.5 Polinomios de Jacobi
Estos polinomios, tambien conocidos como polinomios hipergeometricos, se construyen
como las soluciones de la ecuacion diferencial de Jacobi [19]. Al depender de dos
parametros adicionales α, β > −1, dan a lugar a familias mucho mas variadas. De hecho,
Appendix B. Familias de Funciones Ortogonales 78
las anteriores familias son casos particulares de los polinomios de Jacobi mediante las
relaciones [3]:
Li(ξ) = J(0,0)i (ξ) (B.7)
Loi(ξ) =i+ 2
2J(1,1)i (ξ) (B.8)
Ti(ξ) =i!√π
Γ(i+ 1/2)J(−1/2,−1/2)i (ξ) (B.9)
Ti(ξ) =i!√π
2 · Γ(i+ 3/2)J(1/2,1/2)i (ξ) (B.10)
Polinomios de Jacobi
J(α,β)0 (ξ) = 1
J(α,β)1 (ξ) = 1
2(α+ β + 2)ξ + 12(α− β)
J(α,β)2 (ξ) = 1
8(α+ β + 3)(α+ β + 4)ξ2 + 14(α− β)(α+ β + 3)ξ
+18 [(α− β)2 − (α+ β + 4)]
J(α,β)3 (ξ) = 1
48(α+ β + 4)(α+ β + 5)(α+ β + 6)ξ3 + 116(α− β)(α+ β + 4)(α+ β + 5)ξ2
+ 116(α+ β + 4)[(α− β)2 − (α+ β + 6)]ξ + 1
48(α− β)[(α− β)2 − (3α+ 3β + 16)]. . .
J(α,β)i (ξ) = (−1)i
2ii!(1− t)−α(1 + t)−β di
dξi((1− t)i+α(1 + t)i+β)
Tabla B.5: Primeros miembros de la familia de polinomios de Jacobi (Adaptado de[3])
Para el calculo de los polinomios de Proriol de orden 3 son de interes los polinomios de
Jacobi de la forma J(2k+1,0)l (2η−1). A continuacion se presentan los polinomios usados:
J(7,0)0 (2η − 1) = 1
J(5,0)1 (2η − 1) =
7
2(2η − 1) +
5
2= 7η − 1
J(3,0)2 (2η − 1) =
21
4(2η − 1)2 +
9
2(2η − 1) +
1
4= 21η2 − 12η + 1
J(1,0)3 (2η − 1) =
35
8(2η − 1)3 +
15
8(2η − 1)2 − 15
8(2η − 1)− 3
8= 35η3 − 45η2 + 15η − 1
(B.11)
B.2 Familias de Funciones 2D
Para el caso bidimensional triangular el numero de familias especialmente conocidas y
relevantes son mucho mas reducidas. En este caso se menciona unicamente las familias
de Appell y Proriol. Por simplicidad en la notacion, se introduce la tercer coordenada
baricentrica ζ := 1− ξ − η.
Appendix B. Familias de Funciones Ortogonales 79
B.2.1 Polinomios de Appell
Estos polinomios se conciben como una generalizacion simetrica con respecto a ξ y η
de los polinomios de Jacobi a dos dimensiones [10]. Si bien estos polinomios no son
formalmente ortogonales segun la Definicion 2.1, sı satisfacen la siguiente propiedad de
ortogonalidad parcial/incompleta (respecto a la funcion de pesos unitaria (w(ξ, η) = 1):∫∫TξpηqAkl(ξ, η) dξdη = 0, ∀p, q : p+ q < k + l. (B.12)
(En este caso T representa el triangulo estandar definido entre los vertices (0, 0), (1, 0)
y (0, 1)). Esta propiedad se puede demostrar por integracion directa, como se observa
en [3]. Esto es, el polinomio Akl(ξ, η) es ortogonal a cualquier polinomio de orden
estrictamente menor que k+ l, ya que es ortogonal a cualquier monomio ξpηq, p+ q <
k + l que se presente. En particular, es ortogonal a Apq(ξ, η). Reversando los roles de
los ındices k, l y p, q, se concluye entonces que los polinomios Akl(ξ, η) son ortogonales
a todo otro polinomio Aij(ξ, η) excepto cuando k + l = i+ j.
Aunque se pueden generalizar a un conjunto de polinomios completamente ortogonales
acordes a la definicion dada, estos nuevos polinomios pierden varias de las propiedades
que originalmente los hacen utiles en el calculo de funciones de interpolacion.
Polinomios de Appell
A00(ξ, η) = 1A10(ξ, η) = ζ − ξ = 1− 2ξ − ηA01(ξ, η) = ζ − η = 1− ξ − 2ηA20(ξ, η) = 2ζ(ζ − 4ξ) + 2ξ2
A11(ξ, η) = ζ(ζ − 2ξ − 2η) + 2ξηA02(ξ, η) = 2ζ(ζ − 4η) + 2η2
. . .
Akl(ξ, η) = ∂k+l
∂ξk∂ηl
(ξkηlζk+l
)Tabla B.6: Primeros miembros de la familia de polinomios de Appell (Adaptado de
[3])
B.2.2 Polinomios de Proriol
Por su parte, los polinomios de Proriol son ortogonales en su totalidad, haciendolos
especialmente atractivos para construir las funciones de interpolacion requeridas para
las soluciones por metodos espectrales. De manera concreta, para la implementacion
del caso m = 3 con un dominio triangular (i.e. polinomios completos de orden 3, o con
10 nodos de interpolacion) se calculan manualmente de manera explıcita los terminos
Appendix B. Familias de Funciones Ortogonales 80
de orden hasta 3 de acuerdo con los polinomios calculados anteriormente para Legendre
(en la Ecuacion B.3) y Jacobi (en la Ecuacion B.11).
Polinomios de Proriol
P00(ξ, η) = 1P10(ξ, η) = ξ − ζ = 2ξ + η − 1P01(ξ, η) = 3η − 1P20(ξ, η) = 6ξ2 + 6ξη + η2 − 6ξ − 2η + 1P11(ξ, η) = (2ξ + η − 1)(5η − 1)P02(ξ, η) = 10η2 − 8η + 1P30(ξ, η) = (2ξ + η − 1)(10ξ2 + 10ξη + η2 − 10ξ − 2η + 1)P21(ξ, η) = (6ξ2 + 6ξη + η2 − 6ξ − 2η + 1)(7η − 1)P12(ξ, η) = (2ξ + η − 1)(21η2 − 12η + 1)P03(ξ, η) = 35η3 − 45η2 + 15η − 1. . .
Pkl(ξ, η) = Lk
(2ξ1−η − 1
)(1− η)kJ
(2k+1,0)l (2η − 1)
Tabla B.7: Primeros miembros de la familia de polinomios de Proriol
Bibliografıa
[1] D.A. Kopriva. Implementing Spectral Methods for Partial Differential Equations:
Algorithms for Scientists and Engineers, chapter Spectral Element Methods, pages
293–354. Scientific Computation. Springer, 2009. ISBN 9789048122615.
[2] L.N. Trefethen. Spectral Methods in MATLAB. Software, Environments, and Tools.
Society for Industrial and Applied Mathematics, 2000. ISBN 9780898714654.
[3] C. Pozrikidis. Introduction to Finite and Spectral Element Methods using MATLAB.
Taylor & Francis, 2005. ISBN 9781584885290.
[4] G. Karniadakis and S. Sherwin. Spectral/hp Element Methods for Computational
Fluid Dynamics: Second Edition. Numerical Mathematics and Scientific Computa-
tion. OUP Oxford, 2013. ISBN 9780199671366.
[5] S.J. Sherwin and G.E. Karniadakis. A triangular spectral element method; appli-
cations to the incompressible navier-stokes equations. Computer Methods in Ap-
plied Mechanics and Engineering, 123(1–4):189 – 229, 1995. ISSN 0045-7825. doi:
http://dx.doi.org/10.1016/0045-7825(94)00745-9.
[6] F.N. van de Vosse and P.D. Minev. Spectral Element Methods: Theory and Appli-
cations/ F.N. Van de Vosse and P.D. Minev. EUT report. Eindhoven University
of Technology, Faculty of Mechanical Engineering, 1996. ISBN 9789038603186.
[7] F.J. Sayas. A gentle introduction to the finite element method, 2008. URL http:
//www.imati.cnr.it/marini/didattica/Metodi-engl/Intro2FEM.pdf.
[8] C. Kleinstreuer. Biofluid Dynamics: Principles and Selected Applications. Taylor
& Francis, 2006. ISBN 9780849322211.
[9] F.M. White. Fluid Mechanics. McGraw-Hill series in mechanical engineering.
McGraw-Hill, 2011. ISBN 9780071311212.
[10] M.G. Blyth and C. Pozrikidis. A lobatto interpolation grid over the triangle. IMA
journal of applied mathematics, 71(1):153–169, 2006.
81
Bibliografıa 82
[11] L.N. Trefethen. Approximation Theory and Approximation Practice. Siam, 2013.
ISBN 9781611972405.
[12] M.G. Blyth, H. Luo, and C. Pozrikidis. A comparison of interpolation grids over the
triangle or the tetrahedron. Journal of Engineering Mathematics, 56(3):263–272,
2006. ISSN 0022-0833. doi: 10.1007/s10665-006-9063-0. URL http://dx.doi.
org/10.1007/s10665-006-9063-0.
[13] L.P. Bos. Bounding the lebesgue function for lagrange interpolation in a simplex.
Journal of Approximation Theory, 38(1):43 – 59, 1983. ISSN 0021-9045. doi: http:
//dx.doi.org/10.1016/0021-9045(83)90140-5.
[14] R. Pasquetti and F. Rapetti. Spectral element methods on unstructured meshes:
which interpolation points? Numerical Algorithms, 55(2-3):349–366, 2010.
[15] D.A. Samano and M. Sen. Mecanica de fluidos, 2009. URL http://www3.nd.edu/
~msen/MecFl.pdf.
[16] C. Shen and J.M. Floryan. Low reynolds number flow over cavities. Physics of
Fluids (1958-1988), 28(11):3191–3202, 1985.
[17] J.R. Koseff and R.L. Street. The lid-driven cavity flow: a synthesis of qualitative
and quantitative observations. Journal of Fluids Engineering, 106(4):390–398, 1984.
[18] K. Cooper and L. Torczon. Engineering a compiler. Elsevier, 2011.
[19] T.S. Chihara. An introduction to orthogonal polynomials. Courier Dover Publica-
tions, 2011.
[20] S. Chapra and R. Canale. Numerical Methods for Engineers. McGraw-Hill Educa-
tion, 2014. ISBN 9780073397924.
[21] B. Sundermann. Lebesgue constants in lagrangian interpolation at the fekete points.
Ergebnisbericht der Lehrstuhle Math III, VIII, 44, 1980.