Subido por Carlos Ramos

Tidal Coastal Basin Model

Anuncio
Modelación numérica de la dinámica de un mar
abierto, en precencia de fricción y teniendo en
cuenta la rotación de la Tierra, con forzamiento
de marea
Carlos Ramos Pérez
Introducción:En este trabajo vamos a explicar un modelo sencillo para describir la dinámica de un mar abierto,en presencia de fricción no lineal, la fuerza
de coriolis y el forzamiento de marea, vamos a presentar el código presentado
por los autores del libro ’The Dynamics of coastal MOdels’, analizarlo de forma
breve, resaltar algunos puntos que pueden ser mejorables del mismo y vamos a
presentar el mismo código traducido a python y en cierta medida optimizado.
1. El modelo
El modelo que vamos a utilizar para las simulaciones descirbe un cuerpo de agua
bidimensional, cerrado por una parte y con comunicacion con el océano. Presenta una friccı́on no lineal y para estos estudios las variables se dividieron entre
su escala caracterı́stica para hacerlas adimensionales. Tenemos dos ecuaciones
(1) para la conservación del momento y (2) para la conservación del volumen.
∂ui
∂η
=−
− Cd |u|ui − 2ω × ui
∂t
∂xi
(1)
∂η
∂(1 + η)ui
=−
∂t
∂xi
(2)
2. Estrategia Numérica
Para resolver de forma numérica estas ecuaciones se usó el método de diferencias
finitas en las componentes espaciales, sobre una malla regular Arakawa C, donde
los valores de la velocidad fueron calculados en los lados de las celdas y el
volúmen en el centro de las mismas. Para la componente temporal se usó un
método de paso simple (Euler). Se escogieron estas configuraciones que son
las más sencillas en aras de hacer un código mas simple, lo que trae como
consecuencia la necesidad de un paso temporal muy pequeño para garantizar la
estabilidad, en casos reales deben utilizarse mejores esquemas como los metodos
1
de Runge-Kutta o predictor-corrector. Las condiciones de fronteras se escogieron
cerradas, simulando la costa.
3. El programa(Matlab)
A continuación de presentamos el código presentado por los autores del texto
citado anteriormente ??, lo vamos a describir a grandes rasgos y vamos a resaltar
algunos cambios y errores.
Aquı́ es de destacar que los autores no usaron todas las facilidades intrı́nsecas
de un lenguaje de alto nivel como MatLab, con el objetivo expreso de que el
código fuera facilmente adaptable a Fortran. En la primera parte(azul claro)
se declaran las variablers que van a ser constantes en nuestro program,a y que
describen el dominio, asi como los pasos tempporales y espaciales de la malla,
además de algunas constantes fı́sicas como el parámetro de rozamiento y la frecuencia de Coriolis. Luego se definen los forzamientos externos debidos a la
marea. A continuación comienza la iteración temporal donde se usa un ciclo
’while’ para iterar mientras el tiempo sea menor que cierto tiempo final. Dentro de este ciclo se hacen los calculos para cada celda de la malla, aplicando
el método de diferencias finitas. En un primer paso para la componente u de
la velocidad (violeta), donde se repite innecesariamente un ciclo ’for’, que fue
optimizado en el código en python.
Después (en verde) se resuelve la frontera izquierda de la componente u de
la velocidad, que es la forntera que tiene forzamiento de marea.
Luego (en amarillo) se resuelve el método de diferencias finitas para la componente v de la velocidad.
A continuación (en rojo) se calcula la variación del volúmen para cada celda
a partir de las velocidades calculadas anteriormente.
Por último (en azul fuerte) se calculan las condiciones de fronteras, es de
destacar que para u solo se calcula la frontera derecha ya que la izquierda
depende del forzamiento de marea. Aqui hay errores, ya que se repiten las
asignaciones de manera contradictoria, lo que es provablemente un error de
tipografı́a.
Como hemos podido observar, el código no está completamente optimizado
y presenta algunos errores y reiteraciones innecesarias.
2
Fig. 1: Código en MatLab
4. Python
En esta sección presentaremos el código en python, escrito a partir del programa
en MatLab y con algunas optimizaciones, aunque el código es aún mejorable,
además se agrega una función para graficar los resultados.
# s e importan l a s l i b r e r i a s n e c e s a r i a s
import numpy a s np
import m a t p l o t l i b . p y p l o t a s p l t
from m a t p l o t l i b . c o l o r s import BoundaryNorm
from m a t p l o t l i b . t i c k e r import MaxNLocator
3
def p l o t f u n c t i o n (M, N, u , v , eta , t ) : # f u n c i o n de p l o t e o
paso = 1
plt . figure ()
l e v e l s = MaxNLocator ( n b i n s =25). t i c k v a l u e s ( −.05 , . 0 5 )
# s e d e f i n e e l numero de c o n t o r n o s d e l mapa
cmap = p l t . get cmap ( ’ coolwarm ’ )
norm = BoundaryNorm ( l e v e l s , n c o l o r s=cmap . N, c l i p=True )
# s e d e f i n e e l t i p o de p a l e t a de c o l o r e s
x =
y =
u =
v =
eta
np . l i n s p a c e ( 0 , 1 , M − 2 )
np . l i n s p a c e ( 0 , 1 , N − 1 )
u [ 2 : − 1 , 1: −1]
v [ 2 : − 1 , 1: −1]
= e t a [ 2 : − 1 , 1: −1]
# s e preparan l a s v a r i a b l e s para g r a f i c a r
yy , xx = np . meshgrid ( y , x )
# creamos l o s c o n t o r n o s
c o n t = p l t . c o n t o u r f ( yy , xx , eta , l e v e l s=l e v e l s , cmap=cmap )
p l t . c o l o r b a r ( cont )
p l t . c o n t o u r ( yy , xx , eta , l e v e l s=l e v e l s , c o l o r s= ’ k ’ )
p l t . q u i v e r ( yy [ 0 : : paso , 0 : : paso ] , xx [ 0 : : paso , 0 : : paso ] , 100 ∗
u [ 0 : : paso , 0 : : paso ] , 100 ∗ v [ 0 : : paso , 0 : : paso ] )
p l t . t i t l e ( ’ O p e n C o a s t a l B a s i n d y n a m i c s w i t h p e r i o d i c t i d a l f o r c i n g {0} ’ . format ( t ) )
p l t . s a v e f i g ( ’ outputs ncdm / q u i v e r s { 0 } . png ’ . format ( t ) )
plt . close ()
# e d i t a m o s y s a l v a m o s l o s d e t a l l e s de l a f i g u r a
#########################################################################
#############
COMIENZA EL METODO
##################################
# D e c l a r a c i o n de c o n s t a n t e s y v a r i a b l e s n e c e s a r i a s
N = 30
M = 20
dx = 1 . /N
dy = dx
dt = 0 . 0 0 1
tau = 20
f p r i m e = np . p i /10
tidal period = 5
a = np . z e r o s ( (M + 1 ) )
4
u = np . z e r o s ( (M + 1 , N + 1 ) )
v = np . z e r o s ( (M + 1 , N + 1 ) )
e t a = np . z e r o s ( (M + 1 , N + 1 ) )
px = np . z e r o s ( (M + 1 , N + 1 ) )
py = np . z e r o s ( (M + 1 , N + 1 ) )
v f = np . z e r o s ( (M + 1 , N + 1 ) )
u f = np . z e r o s ( (M + 1 , N + 1 ) )
# Definimos e l f o r z a m i e n t o
a [ 1 :M/ 5 ] = 0 . 0 5
a [ 4 ∗M/ 5 :M] = −0.05
t = .5
t f i n a l = 6.5
count = 71
# Comienza l a i t e r a c i i o n t e m o p r a l
while t < t f i n a l :
f o r j in np . a r a n g e (M) :
f o r i in np . a r a n g e ( 1 , N ) : # hacemos un s o l o c i c l o por i
px [ j , i ] = ( e t a [ j , i ] − e t a [ j , i − 1 ] ) / dx
vf [ j , i ] = (v [ j , i ] + v [ j + 1 , i ] + v [ j , i + 1]
+ v[ j + 1 , i − 1]) / 4
u [ j , i ] = u [ j , i ] + dt ∗ (−px [ j , i ] + 0 ∗ f p r i m e
∗ v f [ j , i ] − u [ j , i ] / tau )
#c a l c u l a m o s u en l a f r o n t e r a i z q u i e r d a
f o r j in np . a r a n g e (M) :
px [ j , 0 ] = ( e t a [ j , 0 ] − a [ j ] ∗ np . s i n ( 2 ∗ np . p i ∗
t / t i d a l p e r i o d ) ) / dx
vf [ j , 0] = v [ j , 0] + v [ j + 1 , 0] / 2
u [ j , 0 ] = u [ j , 1 ] + dt ∗ (−px [ j , 0 ] − u [ j , 0 ] / tau )
f o r i in np . a r a n g e ( 1 , N ) : # Calculamos l a
f o r j in np . a r a n g e ( 1 , M) :
py [ j , i ] = ( e t a [ j , i ] − e t a [ j −1,
uf [ j , i ] = (u [ j , i ] + u [ j , i + 1]
+ u[ j − 1 , i + 1]) / 4
v [ j , i ] = v [ j , i ] + dt ∗ (−py [ j ,
∗ u f [ j , i ] − v [ j , i ] / tau )
componente v
i ] ) / dy
+ u[ j − 1, i ]
i ] + 0 ∗ fprime
f o r j in np . a r a n g e (M) :
# Calculamos l a s o b r e e l e v a c i o n
f o r i in np . a r a n g e (N ) :
e t a [ j , i ] = e t a [ j , i ] − dt ∗ ( ( u [ j , i + 1 ] − u [ j , i ] ) / dx +
5
( v [ j + 1 , i ] − v [ j , i ] ) / dy )
# Calculamos u y v en l a f r o n t e r a , o m i t i e n d o l a r e i t e r a c i o n d e l
#l i b r o y usando una s i n t a x i s p r o p i a de l e n g u a j e s de a l t o n i v e l
u [ : , N] = 0
v [M, : ] = 0
v[0 , : ] = 0
# llamamos a l a f u n c i o n de p l o t e o cada 70 i n t e r v a l o s t e m p o r a l e s
i f np . mod( count , 7 0 ) == 0 :
p l o t f u n c t i o n (M, N, u , v , eta , t )
count = count + 1
t = t + dt
# Aqui s a l v a m o s en un formato b i n a r i o p r o p i o de python e l v a l o r
#f i n a l de l a s v a r i a b l e s d e i n t e r e s , l u e g o de cumplido t o d o e l
#i n t e r v a l o t e m p o r a l
np . s a v e ( ’M’ , M)
np . s a v e ( ’N ’ , N)
np . s a v e ( ’ u ’ , u )
np . s a v e ( ’ v ’ , v )
np . s a v e ( ’ e t a ’ , e t a )
np . s a v e ( ’ time ’ , t f i n a l )
5. Algunos Resultados
A continuación mostraremos algunos resultados obtenidos usando el modelo
antes descrito y el programa en python. En todos los gráficos que presentaremos
a continuación en colores mostraremos la sobreelevacion adimensional de el nivel
del mar y los vectores de velocidad.
5.1. Una entrada centrada
Aqui podemos observar cómo los vectores tratan de moverse paralelos a las
lineas de igual presión, moviéndose de zonas de mayor a zonas de menor presion
de acuerdo a un valance geotrófico, aunque nunca es totalemtne paralelo debido
a la componente disipativa de la ecuación del modelo, que representan una
desviación del modelo geostrófico. Se pueden observar ciertas inestabilidades en
la frontera izquierda, que pueden ser salvables escogiendo un esquema numérico
más avanzado.
6
Fig. 2: Una entrada centrada
5.2. Otras configuraciones de la entrada
Fig. 3: Una entrada
Fig. 4: Dos entradas
7
Fig. 5: Sin Coriolis
Fig. 6: Dos entradas en fase
6. Conclusiones
De manera fgeneral se implementó un modelo para describir la dinámica de
un mar con comunicación con el océano con forzamiento de marea, pudimos
hacer determinados experimentos numéricos para entender la dinámica de estos
sistemas, se recomienda implementar el modelo en un lenguaje de bajo nivel,
por ejemplo, fortran, para incrementar la eficiencia del mismo.
OBSERVAIÓN: En la carpeta compartida en el drive estarán algunas animaciones realizadas a partir de los experimentos numéricos realizados
8
Descargar