Está en la página 1de 30

Curso de El Método de los Elementos

Finitos

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 2

Módulo 1: Introducción
Unidad 2: Ecuación de Poisson

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 3

Presentación:
La plataforma de Fenics es programable mediante el lenguaje de programación de
python, por lo que debemos aprender mínimamente los aspectos básicos del lenguaje y la
aplicación de las librerías más utilizadas de forma de poder iniciar a trabajar (dado que no
es un curso de python a medida que se haga necesario iremos introduciendo los
conceptos del lenguaje). Como paso previo y de forma de ver una aplicación luego del
arduo esfuerzo de instalación, vamos a ver como utilizar Fenics para resolver la ecuación
de Poisson.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 4

Objetivos:

● Familiarizarse con el lenguaje de programación de Python


● Obtener un primer acercamiento a la resolución aplicada a la ecuación de Poisson

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 5

Bloques temáticos:

1. Teoría de ecuación de Poisson

2. Receta para la resolución de problemas

3. Conceptos del lenguaje de programación

4. Primer ejemplo mediante Fenics

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 6

Consignas para el aprendizaje colaborativo


En esta Unidad los participantes se encontrarán con diferentes tipos de actividades que,
en el marco de e los fundamentos del MEC*, los referenciarán a tres comunidades de
aprendizaje, que pondremos en funcionamiento en esta instancia de formación, a los
efectos de aprovecharlas pedagógicamente:

● Los foros proactivos asociados a cada una de las unidades.


● La Web 2.0.
● Los contextos de desempeño de los participantes.

Es importante que todos los participantes realicen algunas de las actividades sugeridas y
compartan en los foros los resultados obtenidos.

Además, también se propondrán reflexiones, notas especial


especiales
es y vinculaciones a
bibliografía y sitios web.

El carácter constructivista y colaborativo del MEC nos exige que todas las actividades
realizadas por los participantes sean compartidas en los foros.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 7

Tomen nota
Las actividades son opcionales y pueden realizarse en forma individual, pero siempre es
deseable que se las realice en equipo, con la finalidad de estimular y favorecer el trabajo
colaborativo y el aprendizaje entre pares. Tenga en cuenta que, si bien las actividades
son opcionales, su realización
alización es de vital importancia para el logro de los objetivos de
aprendizaje de esta instancia de formación. Si su tiempo no le permite realizar todas las
actividades, por lo menos realice alguna, es fundamental que lo haga. Si cada uno de los
participantes
ntes realiza alguna, el foro, que es una instancia clave en este tipo de cursos,
tendrá una actividad muy enriquecedora.

Asimismo, también tengan en cuenta cuando trabajen en la Web, que en ella hay de todo,
cosas excelentes, muy buenas, buenas, regula regulares,
res, malas y muy malas. Por eso, es
necesario aplicar filtros críticos para que las investigaciones y búsquedas se encaminen a
la excelencia. Si tienen dudas con alguno de los datos recolectados, no dejen de consultar
al profesor-tutor.
tutor. También aprovechen en el foro proactivo las opiniones de sus
compañeros de curso y colegas.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 8

1. Teoría de ecuación de Poisson


La ecuación de Poisson en una dimensión, con condiciones de borde puede expresarse
de la siguiente forma:

−𝛻 𝑢(𝑥) = 𝑓(𝑥), 𝑐𝑜𝑛 𝑥 𝑒𝑛 Ω (Ecuación 1)

𝑢(𝑥) = 𝑢 (𝑥), 𝑐𝑜𝑛 𝑥 𝑒𝑛 𝜕Ω


Ω (Ecuación 2)

Aquí:

● x =(x1, x2, …., xn) en este caso x = (x, y)

● u=u(x)) es la función desconocida.

● f(x)) es una función preestablecida.

●   Es el operador Laplaciano, el cual también puede escribirse como ∆

● Ω es el espacio de dominio.

● 𝜕Ω es el borde del espacio de dominio.

Repaso:

El Laplaciano o divergencia del gradiente se puede expresar en ecuaciones


rectangulares como:

𝜕 𝑢 𝜕 𝑢 𝜕 𝑢
𝛻
𝛻. 𝛻𝑢 = 𝛻 𝑢 = + +
𝜕𝑥 𝜕𝑦 𝜕𝑧
En coordenadas polares como:

𝜕 𝑢 𝜕 𝑢 𝜕 𝑢
𝛻
𝛻. 𝛻𝑢 = 𝛻 𝑢 = + +
𝜕𝑟 𝜕𝜃 𝜕𝑧
En coordenadas esféricas como:

.
𝜕 𝑢 𝜕 𝑢 1 𝜕 𝑢 2 𝜕𝑢 𝑐𝑜𝑡𝜃 𝜕𝑢
𝛻. 𝛻𝑢 = 𝛻 𝑢 = + + + +
𝜕𝑟 𝜕𝜃 𝑟 𝑠𝑖𝑛 𝜃 𝜕∅ 𝑟 𝜕𝑟 𝑟 𝜕𝜃

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 9

En dos dimensiones y coordenadas rectangulares podes escribir la ecuación de Poisson


como:

− − = 𝑓(𝑥, 𝑦) (Ecuación 3)

Obviamente aquí “u” es una función dependiente de dos variables u(x,y) definida sobre el
espacio de dos dimensiones Ω
Ω.

La ecuación de Poisson posee numerosas aplicaciones, en contextos físicos como:

● Conducción de calor

● Electrostática

● Difusión de sustancias

● Ondas de agua, etc...

Para resolver este tipo de ecuaciones en Fenics, debemos realizar los siguientes pasos:

● Identificar el dominio Ω, la ecuaci


ecuación
ón de derivadas parciales, sus condiciones de
borde y la función “f”.

● Reformular la ecuación diferencial como un problema variacional de elementos


finitos.

● Escribir un programa de Python que defina el dominio computacional, el problema


variacional, las condiciones de contorno y los términos fuente, usando las
abstracciones FEniCS correspondientes.

● Llamar a FEniCS para resolver el problema del valor límite y, opcionalmente,


extender el programa para calcular cantidades derivadas, como flujos y promedios,
y posterior visualización de los resultados.

2. Receta para la resolución de problemas


La metodología para convertir una ecuación diferencial en un problema variacional es
multiplicar la ecuación diferencial
erencial por una función ““v” (llamada de testigo o test) e integrar
la ecuación resultante sobre el dominio Ω y realizar una integración ón por partes de los

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 10

términos con derivadas de segundo orden. A la función ““u”” se la suele llamar de prueba o
trial.

Multiplicando
plicando nuestra ecuación por la función testigo e integrando en el dominio nos
queda:

−∫ (𝛻 𝑢)𝑣 𝑑𝑥 = ∫ 𝑓𝑣 𝑑𝑥 (Ecuación 4)

Aquí “dx” denota el elemento diferencial de integración sobre el dominio  .

Una regla habitual es tratar de mantener el orden de derivación de “u” y “v” lo más bajo
posible. Aquí tenemos una derivada espacial de segundo orden en “u”, que podemos
transformar en derivadas de primer orden en “u” y “v” mediante la integración por partes
de la siguiente manera:

−∫ (𝛻 𝑢)𝑣 𝑑𝑥 = ∫ 𝛻𝑢. 𝛻𝑣 𝑑𝑥 − ∫ 𝑣 𝑑𝑠 = ∫ 𝑓𝑣 𝑑𝑥 (Ecuación


5)

En donde:

= 𝛻𝑢. 𝑛 = g

Es la derivada de u en la dirección normal externa al dominio n en el borde.

Nos queda

∫  𝛻𝑢. 𝛻𝑣 𝑑𝑥 = ∫ 𝑓𝑣 𝑑𝑥 + ∫ 𝑔𝑣 𝑑𝑠 (Ecuación 6)

La bibliografía de Fenics suele utilizar forma bilineal 𝑎(𝑢, 𝑣)

𝑎(𝑢, 𝑣) = 𝐿(𝑣)

Nota:: El nombre bilineal deriva del hecho que, cuando se fija cualquiera de las variables,
la función resulta lineal en la otra.

Por lo que tenemos para la ecuación de Poisson, que:

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 11

𝑎(𝑢, 𝑣) = ∫ 𝛻𝑢. 𝛻𝑣 𝑑𝑥 (Ecuación 7)

𝐿(𝑣) = ∫ 𝑓𝑣 𝑑𝑥 + ∫ 𝑔𝑣 𝑑𝑠 (Ecuación 8)

Para resolver el problema med


mediante
iante Fenics, como veremos, solo necesitamos definir:

1. Elegir el espacio V mediante la especificación del dominio (el mallado) y el tipo de


función espacial (grado de polinomio y tipo).

2. Expresar la ecuación en derivadas parciales como un problema variacional,


encontrando u tal que se cumpla la ecuación 6.

Si tomamos v = 0 en todo el límite ∂Ω, el segundo término


érmino en el lado derecho de
(Ecuación 5) desaparece, por lo que:

∫  𝛻𝑢. 𝛻𝑣 𝑑𝑥 = ∫ 𝑓𝑣 𝑑𝑥 (Ecuación 9)

Si requerimos que esta ecuación se mantenga para toda función testigo v en algún
espacio adecuado 𝑉 , que llamaremos espacio testigo, obtenemos un problema
matemático bien definido que determina de forma única la solución u que se encuentra en
algún espacio de función (pos
(posiblemente
iblemente diferente) V, que llamaremos de prueba.

Nota: La ecuación 9 se denomina como la forma débil o variacional del problema del valor
límite original expresado por las ecuaciones 1 y 2. De esta forma, nuestro problema se
puede definir como encontrar la función u ∈ V tal que:

∫  𝛻𝑢. 𝛻𝑣 𝑑𝑥 = ∫ 𝑓𝑣 𝑑𝑥 ∀𝑣 ∈ 𝑉 (Ecuación 10)

En donde:

𝑉 = {𝑣 ∈ 𝐻 (𝛺): 𝑣 = 𝑣 𝑒𝑛 𝜕Ω }

𝑉 = {𝑣 ∈ 𝐻 (𝛺): 𝑣 = 0 𝑒𝑛 𝜕Ω }

En resumen, H1(Ω) es el espacio Sobolev matemáticamente conocido que contiene


funciones v de tal manera que 𝑣 y |𝛻𝑣| tienen integrales finitas sobre Ω (lo que significa
que las funciones son continuas). La solución de la ecuación en derivadas parciales
subyacente debe estar en un espacio de funciones donde las derivadas también sean
Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 12

continuas, pero el espacio Sobolev H1 (Ω) permite funciones con derivados discontinuos.
Este requisito de continuidad más débil de u en la declaración variable (Ecuación 9), como
resultado de la integración por pa
partes,
rtes, tiene grandes consecuencias prácticas cuando se
trata de construir espacios de funciones de elementos finitos. En particular, permite el uso
de espacios de funciones polinomiales por partes; es decir, espacios funcionales
construidos uniendo funcione
funciones
s polinómicas en dominios simples como intervalos,
triángulos o tetraedros.

El problema variacional (Ecuación 6) es un problema continuo: define la solución en el


espacio de funciones finito-dimensional
dimensional V. El método de elementos finos para la ecuación
de Poisson
oisson encuentra una solución aproximada del problema variacional. La solución
discreta aproximada se denota como 𝑢 perteneciente al dominio 𝑉 . La aproximación
numérica que debemos encontrar se puede expresar como:

∫   𝑢 . 𝛻𝑣 𝑑𝑥 = ∫ 𝑓𝑣 𝑑𝑥 ∀𝑣 ∈ 𝑉 ⊂ 𝑉 (Ecuación 11)

Este tipo de problemas variacionales son los que Fenics puede resolver.

Nota importante:: En lo sucesivo para ser consistente con la notación de la bibliografía


de Fenics nos referiremos a 𝑢 simplemente como u

3. Conceptos del lenguaje de programación


El lenguaje que utilizamos para programar en Fenics es Python, por lo que a continuación
vamos a ver los principios básicos del lenguaje utilizando el paradigma de Programación
Orientada a Objetos, de forma de comprender los códigos que vamos a utilizar. Se
recomienda que el alumno profundice en este lenguaje para poder tener un mayor control
sobre los trabajos realizados.

Dado que se asume que el alumno posee conceptos de programación, si simplemente


indicaremos algunos puntos que son propios de python, que se deben tener en cuenta a
la hora de programar.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 13

Variables
Para comenzar, indicaremos que en python a diferencia de otros lenguajes de
programación, debemos tener presente que todos los elementos que manejamos, desde
variables, funciones, archivos, bases de datos, etc, son considerados objetos. Cuando
creamos una variable, esta apunta a un objeto que puede ser de diferentes tipos, por
ejemplo para indicar una variable que guarda un número entero, debemos especificar:

1. Un nombre (variable1)

2. El operador de igualdad (=)

3. El objeto considerado entero (ejemplo 7)

variable1 = 7

Nota:: No hace falta finalizar la instrucción con un punto y coma (;)

Cada vez que creamos una variable:

1 – Se genera un registro en una tabla

2 – Se crea un objeto

3 – Se establece la ruta desde la variable al objeto

El objeto creado posee:

1 – Un indicador de tipo de objeto.

2 – Un contador de referencia para establecer cuándo se puede reclamar el objeto.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 14

Las variables pueden apuntar a diferentes tipos de objetos, como:

Enteros:

variable1 = 7

Strings:

variable1 = “7”

Listas de datos:

variable3 = [“7”, 8, True]

Nota:: Las listas son colecciones de objetos, indicados entre corchetes y separados por
comas, cada objeto en sí puede ser de cualquier tipo, incluso podemos anidar listas
dentro de listas.

Nota 2:: Las listas no son arrays, por lo que no podemos trabajar con matrices como lo
haríamos en álgebra lineal. Para trabajar con arrays, necesitamos importar una librería de
python llamada “numpy” que nos permite expandir las funcionalidades de python con este
tipo de objetos.

Nota 3:: Otros tipos de objetos como diccionarios, tuplas, sets, no será utilizados por ahora
por lo que no tiene sentido introducirlos aquí, si el alumno necesita puede preguntar
mediante la plataforma y en cada caso sol solicitado,
icitado, se brindará una respuesta
complementaria.

Nota 4:: Para imprimir el valor en pantalla se puede utilizar la rutina de python “print”
indicando entre paréntesis lo que quiero mostrar, de la siguiente forma:

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 15

print(variable1)

Uso de Librerías
Python trae muchas librerías que podemos utilizar directamente, pero en el caso de que
queramos agregar una librería de terceros, simplemente abrimos el cmd y mediante el
comando “pip install” (en Linux utilizamos pip3) lo instalamos en la distribución de python
que estamos utilizando en nuestro sistema operativo. Por ejemplo si queremos instalar la
librería “numpy” para trabajar con matrices, lo realizamos de la siguiente manera:

pip3 install numpy

Una vez que la libreria está instalada, las podemos importar desde nuestros programas
mediante el prefijo “import”, e incluso podemos cambiarle el nombre con el que vamos a
trabajar dentro del programa mediante la palabra “as” de la siguiente manera. Para ver un
ejemplo, extendamos python con objetos de array de numpy y creemos una matriz de 3
filas por 4 columnas:

1 import numpy as np
2 A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9,10, 11, 12]])

En la primera línea hemos importado la librería y renombrado mediante el nombre “np”

Para crear un array podemos utilizar la rutina “array” con notación de punto a partir de
“np” y declarar dentro la matriz de datos, indicando cada fila entre corchetes, como si se
tratara de una lista anidada.

Funciones
Las variables
les se utilizan para almacenar información, en cambio las funciones se utilizan
para realizar algo, como por ejemplo sumar, restar, establecer movimientos complejos de
objetos, etc.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 16

La estructura de una función es como sigue:

1 def printer(mensaje):
2 print('hola' + mensaje)

En primer lugar aparece la declaración de función “def”, luego viene el nombre de la


función, a continuación entre paréntesis se le pueden pasar argumentos que la función
puede utilizar dentro del código, el cual va lue
luego
go de dos puntos “:” en una nueva línea y
aplicando una indentación. La indentación en Python indica que el código indentado se
encuentra dentro de la declaración, por lo que todo el código dentro de la función debe
tener el mismo tipo de indentación en ca
cada
da línea para que se considere dentro del mismo
nivel. Las indentaciones indican niveles.

Para ejecutar el código se llama a la función y se le indican el parámetro a utilizar como


argumentos de la siguiente forma:

Nombre(parámetro1, …......, parámetron)

O sea, el nombre de la función conteniendo los parámetros a ser pasados como


argumentos de la función, en nuestro caso sería por ejemplo:

printer(“Hola Mundo”)

Existen algunas palabras reservadas al trabajar con funciones como “return”

Uso de return
El uso de return es similar a otros lenguajes de programación, en donde se utiliza para
retornar un valor que luego pueda llegar a ser utilizado en otra parte del código u otras
funciones. En el siguiente caso, el valor retornado es guardado dentro de la var
variable a y
luego se imprime a.

1 def printer(mensaje):
2 return mensaje
3
4 a = printer("Hola Mundo")
5 print(a)

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 17

POO – Programación Orientada a Objetos


La programación orientada a objetos (POO) es un paradigma de programación introducido
en la década del 90 que facilita y simplifica el diseño de una aplicación o programa. Posee
varias ventajas con relación a la programación estructurada, entre las que se destaca la
posibilidad de reutilización de código, sin embargo la velocidad de ejecución puede verse
disminuida por lo que en aplicaciones de cálculo numérico es necesario analizar la
conveniencia o no de su uso, en este caso particular un mix entre progra programación
estructurada y POO podría ser lo más recomendable.

Este tipo de programación se basa en cuatro técnicas principales, sin contar la herencia
de la cual trataremos más adelante, y son: abstracción , polimorfismo, acoplamiento
(principio de ocultación)) y encapsulamiento
encapsulamiento.

La POO fue introducida para permitirnos programar de forma similar a cómo


interaccionamos con el mundo que nos rodea, comprendiendo a cada parte del código
como si fuera un objeto, por lo que su utilización, (salvada la barrera de apr
aprender nuevas
estructuras de programación) debería ser más intuitiva.

¿Cómo pensar en objetos?

Pensar en términos de objetos es muy parecido a cómo lo haríamos en la vida real. Por
ejemplo vamos a pensar en un coche para tratar de modelizarlo en un esquema de POO.
Diríamos que el coche es el elemento principal que tiene una serie de características,
como podrían ser el color, el modelo o la marca. Además tiene una serie de
funcionalidades asociadas, como pueden ser ponerse en marcha, parar o estacionar.
Puess en un esquema POO el coche sería el objeto, las propiedades (atributo o variable)
serían las características como el color o el modelo y los métodos (operaciones o
funciones) serían las funcionalidades asociadas como ponerse en marcha o parar.

Vale aclarar,
rar, que los objetos son únicos, no existen dos objetos iguales, de la misma
forma que no existen dos personas iguales, por más que sean mellizos o en el mundo de
hoy, un clon, cada objeto es único.

¿Qué es una clase?

La POO está formada básicamente por cclases,


lases, estas estructuras, que vamos a utilizar
para agrupar los atributos y métodos de un determinado tipo de objeto, nos van a permitir

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 18

definir al mismo. Cuando programamos un objeto y definimos sus características y


funcionalidades en realidad lo que est
estamos
amos haciendo es programar una clase.

¿Cómo definimos una clase en Python?

Vayamos paso a paso, comencemos por mostrar un ejemplo de declaración de clase:

class PrimerClase:
atributo1 = 2
objeto = PrimerClase()

print(objeto.atributo1)

Como vemos podemos


emos indicar los siguientes componentes de la clase:

1.- Palabra reservada al inicio “class”

2.- Nombre de la clase “PrimerClase”

3.- Dos puntos “:”

A continuación para crear un objeto de dicha clase se llama a la clase de forma similar a
cómoo llamaríamos a una función, es decir por su nombre seguido de paréntesis:

objeto = PrimerClase()

Para poder acceder al atributo definido dentro de la clase lo podemos hacer mediante lo
que se denomina notación de punto, es decir escribir el nombre del o
objeto,
bjeto, luego un punto
y luego el atributo al cual hacemos referencia:

objeto.atributo1

Método __init__().
Cuando trabajamos con programación orientada a objetos POO, una de las cosas más
importantes a tener en cuenta, es la forma en que creamos dichos objetos. Como
veremos un poco más adelante la forma correcta de crear los objetos es mediante la
utilización de un método (función) __init__ el cual es un método reservado de Python que

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 19

cumple la función de constructor de la clase a la cual se encuentra as asociada, es decir una


función destinada a inicializar (crear) los objetos de la clase utilizada.

Variables y método de instancia


Las variables de instancia son aquellas que utilizamos para establecer las características
de un determinado objeto, como puede ser el color de ojos en una persona, su altura,
peso, etc. Estas variables siempre van precedidas de la palabra reservada “self”, la cual
debe ser especificada dentro de todo método que vayamos a utilizar. Todos los métodos
que utilicen una variable de in
instancia
stancia (métodos de instancia) deben poseer la declaración
de “self” como primer parámetro entre paréntesis. En el siguiente ejemplo:

usoDeSelf.py
class Persona(object):
def __init__( self,, nombre, edad, sexo ):
self.nombre = nombre
self.edad = edad
self.sexo = sexo
print(self.nombre)

def datos(self, salario):


print("Nombre de la persona: " + self.nombre +
"\n"
n" + "Salario en $: " + str(salario))

objeto = Persona("Juan", 39, "masculino")

objeto.datos(100)

Vemos que el constructor permite establecer tres variables de instancia (nombre, edad y
sexo) las cuales son asignadas mediante:

self.nombre = nombre
self.edad = edad
self.sexo = sexo

El método de instancia datos() tiene como primer co componente


mponente la palabra self (la que nos
permite utilizar dentro del mismo la variable de instancia self.nombre)

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 20

def datos(self, salario):

y como segundo componente un atributo (salario) que debe ser pasado por la invocación
del método a partir del objeto instanciado.

objeto.datos(100)

Variables de clase
Las variables de clase no están asociadas a una instancia en particular, sino directamente
a la clase, es correcto declararlas inmediatamente después del establecimiento del
nombre de la clase. En el eje
ejemplo
mplo dado a continuación la variable “empresa” puede ser
invocada tanto a partir de una instancia:

print(objeto.empresa)

Como directamente a partir de la clase:

print(Persona.empresa)

variablesDeClase.py
class Persona(object):
empresa = "Empresa1"
def __init__( self, nombre, edad, sexo ):
self.nombre = nombre
self.edad = edad
self.sexo = sexo
print(self.nombre)

def datos(self, salario):


print("Nombre de la persona: " + self.nombre +
"\n"
n" + "Salario en $: " + str(salario))

objeto = Persona("Juan", 39, "masculino")


objeto.datos(100)
print(Persona.empresa)

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 21

print(objeto.empresa)
print(objeto.edad)

Métodos de clase – decorador: @classmethod


Los métodos de clase, es decir aquellos que no necesitan de la instancia de un objeto,
pueden ser invocados directamente escribiendo el nombre de la clase y a continuación
con notación de punto, el nombre del método y los atributos que toma.

Los métodos de clase utilizan en su declaración un primer parámetro “cls” de forma


análoga a como declaramos en un método de instancia la palabra “self”, y deben de ser
precedidos por el decorador @classmethod (existen otros decoradores que verem
veremos más
adelante). Veamos un ejemplo

metodosDeClase.py
class Persona(object):

@classmethod
def imprimir(cls, parametro1):
print(parametro1)

Persona.imprimir("valor del parámetro 1")

Métodos estáticos – decorador: @staticmethod


Los métodos
dos estáticos, no necesitan poseer referencia a ningún argumento (como self o
cls) pero sí deben llevar previamente el decorador @staticmethod. Dado que no poseen
en su declaración la palabra “self”, no es posible acceder desde ellos a una variable de
instancia.

metodosEstaticos.py
class Persona(object):

@staticmethod
def imprimir(parametro1):

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 22

print(parametro1)

objeto = Persona()
objeto.imprimir("valor del parámetro 1")

4. Primer ejemplo mediante Fenics


Para comprender cómo utilizar fenics, partiremos de un primer ejemplo que podemos
resolver de forma exacta si consideramos la solución exacta 𝑢 :

{𝑢 (𝑥, 𝑦) = 1 + 𝑥 + 𝑦 𝑓(𝑥, 𝑦) = −6

Paso 1
Ejecutamos jupyter y abrimos una hoja nueva de python, como primera línea de código
escribiremos:

from dolfin import *

En donde lo que estamos realizando es la importación de la librería dolfin, que incluye


todas las rutinas a utilizar con fenics y que utilizamos indicando todo el contenido como el
asterisco (*).

La línea anterior se puede leer como:

Importar todo el contenido de la librería dolfin.

Paso 2
Luego de importar la librería podemos crear una malla elementos finitos formada por 8
por 8 cuadrados divididos en dos, lo cual da un total de 128 celdas, mediante el uso de la
rutina
na “UnitSquareMesh()” y guardamos la información dentro de la variable “mesh”.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 23

mesh = UnitSquareMesh(32, 32)

La malla de puntos seleccionada puede representarse mediante cuadrados de lados de


longitud unitarios según se muestra a continuación:

Para poder verlo podemos adicionar al script la siguiente línea de código:

plot(mesh)

Lo cual permite ver la malla de elementos finitos creada en un gráfico 2D:

Fenics soporta todas las familias simples de la tabla periódica de elementos finitos con su
notación. Esta es una tabla clasificada de forma similar a los elementos de la tabla

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 24

periódica de elementos químicos. Esta tabla esta como pdf de descarga en esta unidad y
se puede encontrar una referencia completa en: http://femtable.org/

PASO 3
Ahora que tenemos la malla de elementos a utilizar podemos crear la función espacial V,
mediante la rutina “FunctionSpace() la cual p
posee tres parámetros:

● Primero:: malla de elementos.

● Segundo:: Familia o tipo de elementos.

● Tercero:: Grado del polinomio.

Podemos guardar dentro de la variable “V” en nuestro caso la función continua de


Lagrange de primer orden, lo cual es igual a polinomios lineales continuos por partes.

V = FunctionSpace(mesh, "Lagrange", 1)

También es equivalente utilizar para esta familia la forma resumida mediante la letra “P”:

V = FunctionSpace(mesh, ‘P’, 1)

Nota: V denota el espacio de función de elemento finito discreto en el que buscamos


nuestra solución.

La solución calculada u será continua a través de los elementos y variará linealmente en x


e y dentro de cada elemento. Las aproximaciones polinómicas de mayor grado sobre
cada celda se obtienen trivialmente al aumentar el tercer parámetro de FunctionSpace,
que luego generará espacios de función de tipo P2, P3, y así sucesivamente. Cambiar el

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 25

segundo parámetro a "DP" crea un espacio de funciones para los métodos discontinuos
de Galerkin.

PASO 4
En matemáticas, distinguimos entre los espacios de testigo y de prueba V y 𝑉 . La única
diferencia en el presente problema son las condiciones de contorno. En Fenics no
especificamos las condiciones de contorno como parte del espacio de funciones, por lo
que es suficiente trabajar con un espacio común V para las funciones testigo y de prueba
en el programa:

u = TrialFunction(V)

v = TestFunction(V)

PASO 5
Ahora podemos considerar las condiciones de borde de Dirichlet, las cuales vienen
representadas por:

bc = DirichletBC(V, u_D, boundary)

Donde:

● u_D es una expresión que define los valores de la solución de borde. Puede ser
expresada como u_D = Expression(formula, degree=1) , en donde la fórmula
debe ser escrita según nomenclatura de C++.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 26

En nuestro caso nuestra fórmula es:

1+𝑥 +𝑦
La cual representaremos como:

1 + 𝑥[0] ∗ 𝑥[0] + 2 ∗ 𝑥[1] ∗ 𝑥[1]

Estamos considerando que la representación de las coordenadas cartesianas se


expresan como :

𝑥 = 𝑥[0]
𝑦 = 𝑥[1]
𝑧 = 𝑥[2]
Una alternativa a la sintaxis anterior sería:

1 + 𝑝𝑜𝑤(𝑥[0], 2) + 2 ∗ 𝑝𝑜𝑤(𝑥[1], 2)

● boundary es una función (u objeto) que define qué puntos pertenecen al límite.
Esta función debe retornar verdadero “True” si el punto considerado se encuentra
dentro del límite de Dirichlet y falso “False” en caso contrario. Debido a errores de
redondeo se suele especificar la condición de borde x = 0 e x = 1 como x<epsilon
e x>1-epsilon.. El valor de épsilon es del orden de la precisión del equipo que
utilizamos y es representado como DOLFIN_EPS según se muestra a
continuación:

def boundary(x):

return x[0] < DOLFIN_EPS or x[1] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS
or x[1] > 1.0 - DOLFIN_EPS

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 27

PASO 6
Ahora podemos expresar el resto de nuestros parámetros f, 𝑎(𝑢, 𝑣) y 𝐿(𝑣)
𝐿

f = Constant(-6.0)

a = dot(grad(u), grad(v))*dx

L = f*v*dx

A f la podríamos haber definido también como: f = Expression(’


Expression(’-6’,
6’, degree=0), pero en
este caso es más eficiente representarla como una constante.

En el caso de “a”, la integral ∫  𝛻𝑢. 𝛻𝑣 𝑑𝑥 puede ser representada de varias formas en


Fenics. En el programa hemos utilizado a = dot(grad(u), grad(v))*dx . En donde dot en
Fenics es un producto to que considera la suma sobre el último índice del primer factor y el
primer índice del segundo factor. En este caso dado que ambos factores son tensores de
rango uno (vectores) la suma resulta sobre un solo índice de 𝛻𝑢 y 𝛻𝑣

PASO 7
Ahora, hemos especificado las formas variacionales y podemos considerar la solución del
problema variacional. Primero, necesitamos definir una “Function” u para representar la
solución. (Tras la inicialización, simplemente se establece en la función cero). Una
“Function” representa una función que vive en un espacio de funciones de elementos
finitos. A continuación, podemos llamar a la función de resolución con los argumentos a
== L, u y bc de la siguiente manera:

u = Function(V)

solve(a == L, u, bc)

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 28

PASO 8
Para visualizar el resultado podemos utilizar la función plot() sobre u:

plot(u)

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 29

Bibliografía utilizada y sugerida

● De Vedia, L. (1997). Monografía Tecnológica N°2 - Mecánica del Continuo (Primera


ed., Vol. 1, pp. 1-320). San Martín - Argentina, Segunda Edición: UNSAM - CNEA.
● Tveito, A. (2016, 06). Solving PDEs in Python The FEniCS Tutorial I.
fenicsproject.org. Obtenido 06, 2016, de https://fenicsproject.org/
● Moreland, K. (2016, 06). The ParaView Tutorial. paraview.org. Obtenido 06, 2016,
de https://www.paraview.org/
● Zienkiewicz, O. (1982). El método de los elementos finitos (1 ed., Vol. 1, pp. 1
1-885).
Barcelona, Publicado: Reverte.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning
p. 30

Lo que vimos:
● En el transcurso de esta unidad hemos visto las bases que necesitamos para
comprender el código de python y cómo aplicar Fenics para resolver la ecuación de
Poisson.

Lo que viene:
● En la siguiente unidad veremos cómo aplicar Fenics a la resolución de problemas
dependientes del tiempo mediante el análisis de la ecuación del calor y su
resolución.

Centro de e
e-Learning SCEU UTN - BA.
Medrano 951 2do piso (1179) // Tel. +54 11 4867 7589 / Fax +54 11 4032 0148
www.sceu.frba.utn.edu.ar/e
www.sceu.frba.utn.edu.ar/e-learning

También podría gustarte