Universidad de Concepción Departamento de Geofı́sica
Universidad de Concepción
Departamento de Geofı́sica
Estrategias Para la Liberación de
Partı́culas
Tomás Valderrama,
Profesor: Andrés Sepúlveda
7 de octubre de 2021
1 Tópicos en Geofı́sica, 7 de octubre de 2021
Índice general
1. Introducción 3
2. Instalación en Linux 5
3. Construcción de un Modelo Básico 7
4. Ejemplos de Casos 11
4.1. Un punto inicial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2. Más de un punto inicial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.3. Distintas profundidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.4. Cono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2
Capı́tulo 1
Introducción
La oceanografı́a, como estudio de los océanos por parte de los seres humanos, es una disciplina
que data desde hace más de 3 mil años como mı́nimo si nos remontamos a los primeros
navegantes fenicios, polinésicos y vikingos. Estos observaron patrones de circulación oceánicos
los cuales usaban para transportarse a través de los mares. Desde esa época hasta ahora la
oceanografı́a ha evolucionado bastante al punto de ser una disciplina académica con varias
ramas y utilidades mucho más diversas que las iniciales.
Dentro de esa evolución se encuentran los modelos numéricos, los cuales podrı́an ser de los más
recientes en el área. Los modelos numéricos son programas diseñados para resolver un conjunto
de ecuaciones dinámicas que representan el comportamiento de la dinámica oceánica. Estos
programas requieren que el usuario entregue una información de entrada, esta información
dependerá de lo que se le pida al modelo, y entregara una simulación del comportamiento de
la zona modelada. Existen varios modelos oceánicos, con distintos lenguajes y utilidades. En
este manual se abordará el OpenDrift, que según sus propios creadores, más que un “modelo
de trayectoria” es un “marco”; debido a su simplicidad. OpenDrift usa salidas del modelo
“Coastal and Regional Ocean COmmunity model” (CROCO) como datos de entrada con los
cuales calculará la trayectoria que se busque.
¿Qué es OpenDrift?
OpenDrift es un paquete de códigos basados en Python para el modelado de partı́culas
Lagrangianas desarrollado por el instituto Metereológico de Noruega con contribuciones de la
comunidad cientı́fica en general. Ası́, OpenDrift puede modelar las trayectorias y el destino
de objetos o sustancias a la deriva en el océano o incluso en la atmósfera. El marco es
genérico y modular, por lo cual presenta varios casos de cálculos de trayectoria como:
Lagrangiano tradicional, derrame de petróleo, búsqueda y rescate aleatorio, huevos oceánicos,
3
Universidad de Concepción Departamento de Geofı́sica
deriva atmosférica, etc. Además, permite la ingestión de un número no especificado de campos
de forzamiento (escalares y vectoriales) de diversas fuentes, incluidos los modelos de océano,
atmósfera y olas eulerianos, pero también mediciones o valores a priori para las mismas variables.
Es inherente un mecanismo de retroceso básico, que utiliza la inversión de signo del vector de
desplazamiento total y el paso de tiempo negativo. OpenDrift es rápido y simple de configurar y
usar en entornos Linux, Mac y Windows, y se puede usar con una experiencia mı́nima o nula en
Python. Está diseñado para ser flexible y los investigadores pueden adaptar o escribir módulos
fácilmente para su propósito especı́fico. OpenDrift también está diseñado para el rendimiento
y las simulaciones con millones de partı́culas se pueden realizar en una computadora portátil.
Además, OpenDrift está diseñado para ser robusto y es de uso operativo diario para el modelado
de preparación para emergencias (deriva de petróleo, búsqueda y rescate y barcos a la deriva)
en el Instituto Meteorológico de Noruega (Dagestad, K. F. et al., 2018).
4 Tópicos en Geofı́sica, 7 de octubre de 2021
Capı́tulo 2
Instalación en Linux
Lo primero que deberemos hacer será instalar Anaconda o Miniconda en nuestros equipos. Se
recomienda Anaconda si es un usuario nuevo de Python y tiene el espacio suficiente para poder
hacer la instalación (al menos 3 GB). Instalar Anaconda le evitará tener que instalar paquetes
individualmente. Las desventajas son que tanto la instalación como las actualizaciones del
sistema demorarán más, además de pesar más que Miniconda. Por otro lado, si tiene experiencia
en usando conda o Python o quiere ahorrar espacio en su equipo instalar Miniconda será
una buena opción. En el caso de usar servidores externos, lo más recomendable será instalar
Miniconda.
Instalación de un ambiente conda
La instalación de un ambiente conda consta de descargar un instalador para el sistema
operativo de los equipos donde se hará la instalación y seguir los pasos propuestos por los
desarrolladores. En este enlace https://docs.conda.io/en/latest/miniconda.html lleva a
la página de selección de instalador y el siguiente es el paso a paso para una instalación de
un ambiente conda en Linux: https://conda.io/projects/conda/en/latest/user-guide/
install/linux.html.
Posterior a esto, haremos una clonación del repositorio GitHub de OpenDrift en el directorio
que queramos trabajar, por ejemplo:
See the following command :
$ pdw
$ / home / user
$ cd / Documents / OD
5
Universidad de Concepción Departamento de Geofı́sica
Ahora estamos en el directorio OD en el que copiaremos el repositorio GitHub See the following
command :
$ git clone https :// github . com / OpenDrift / opendrift . git
Esto nos creará un directorio llamado “opendrift”, al cual accederemos para crear el ambiente
con las dependencias necesarias para la instalación de OpenDrift.
$ cd opendrift
$ conda config -- add channels conda - forge
$ conda env create -f environment . yml
$ conda activate opendrift
$ pip install -e .
Esta sección está basada en la guı́a de instalación de OpenDrift que podrán encontrar en la
Página-Instalación de OpenDrift.
6 Tópicos en Geofı́sica, 7 de octubre de 2021
Capı́tulo 3
Construcción de un Modelo Básico
Inicialización
En primer lugar se recomienda utilizar una lı́nea shebang si tiene varias versiones de Python
instaladas en el equipo, esto asegurará de que el intérprete utilizado sea el primero en la ruta
de su entorno.
Luego importaremos matplotlib el cual es una biblioteca de graficado 2D de Python que produce
figuras de calidad de publicación en una variedad de formatos impresos y entornos interactivos
en todas las plataformas. Se basa en algún backend para representar realmente los gráficos.
Los backends son la capacidad de interactuar entre sı́ que posee matplotlib y admitir distintos
usos; desde integrar matplotlib en interfaces gráficas de usuario como wxpython o pygtk para
crear aplicaciones enriquecidas hasta usan matplotlib en scripts por lotes para generar imágenes
postscript a partir de algunas simulaciones numéricas, y otros en servidores de aplicaciones web
para mostrar gráficos de forma dinámica. Matplotlib puede apuntar a diferentes salidas, y cada
una de estas capacidades se denomina backend; el “frontend” es el código de cara al usuario, es
decir, el código de trazado, mientras que el ”backend”hace todo el trabajo duro detrás de escena
para hacer la figura. Hay dos tipos de backends: backends de interfaz de usuario (para usar
en pygtk, wxpython, tkinter, qt4 o macosx; también denominados “backends interactivos”) y
backends impresos para crear archivos de imagen (PNG, SVG, PDF, PS; también denominados
”backends no interactivos”). El backend predeterminado es el backend “agg”. Este backend solo
procesa archivos PNG.
# !/ usr / bin / env python
import matplotlib
matplotlib . use ( ' Agg ')
7
Universidad de Concepción Departamento de Geofı́sica
Módulos
Posteriormente se importará el módulo “sys” el cual es un módulo de Python integrado
que contiene parámetros especı́ficos del sistema, es decir, contiene variables y métodos que
interactúan con el intérprete y también se rigen por él. “sys.path.append” es una función
incorporada del módulo sys que se puede usar con la variable de ruta para agregar una ruta
especı́fica para que el intérprete busque. El módulo Python OS proporciona funciones sencillas
que nos permiten interactuar y obtener información del sistema operativo e incluso controlar
los procesos hasta un lı́mite. Numpy es una biblioteca de Python que proporciona un objeto
de matriz multidimensional, varios objetos derivados (como matrices y matrices enmascaradas)
y una variedad de rutinas para operaciones rápidas en matrices, que incluyen manipulación
matemática, lógica, de formas, clasificación, selección, entre otras herramientas más. “Datetime”
es un módulo de manejo del tiempo, “timedelta” es una función de este módulo que generalmente
se usa para calcular diferencias en las fechas y también se puede usar para manipulaciones de
fechas en Python.
import sys
sys . path . append ( '/ path / to / opendrift / ')
import os
import numpy as np
from datetime import datetime , timedelta
Readers
Los“readers” o lectores son objetos Python independientes que proporcionan las variables (por
ejemplo, corriente, viento, temperatura) que necesita el modelo para actualizar las propiedades
de las partı́culas. Los lectores normalmente leen desde un archivo (de ahı́ el nombre) o
desde una URL remota, o usan alguna función analı́tica. Existen diferentes clases de lectores
para diferentes tipos de archivos. En este ejemplo se usará dos readers en primer lugar
“reader ROMS native” el cual es un módulo de lectura de archivos tipo ROMS (ROMS Agrif,
Rutgers-ROMS, CROCO) que leerá el archivo de velocidades que usaremos como input. El
siguiente lector a utilizar será “OceanDrift”, el cual es un modelo de deriva 3D simple.
from opendrift . readers import reader_ROMS_native
from opendrift . models . oceandrift import OceanDrift
8 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
Configuración del modelo
Ahora, con lo básico para funcionar hay que definir el objeto de simulación (en este caso
partı́culas sin atributos, i.e. “OceanDrift”) el cual se llamará “o”; loglevel=0 significa que no
se filtrará la información que se muestra en pantalla, esto puede hacer más lento el proceso.
Si queremos quitar toda la información de la pantalla para ahorrar tiempo deberemos usar
loglevel=50. En esta sección podemos ver que definimos un inicio de tiempo y una posición
inicial. Definir el inicio de tiempo servirá para saber en qué punto del tiempo queremos liberar
partı́culas, especialmente si se desea hacer en más de una ocasión. La definición de un punto
inicial es un ejemplo básico, si lo requiere se puede definir más de un punto, o bien un vector
de puntos; soltar partı́culas todos en conjunto o en distintos instantes de tiempo.
o = OceanDrift ( loglevel =0)
filename_nc = ' roms_his . nc '; # Archivo tipo ROMS
mosa_native = reader_ROMS_native . Reader ( filename_nc )
mosa_native . interpolation = ' linearND '
o . add_reader ([ mosa_native ])
time = mosa_native . start_time
# Posici ón inicial
lon = -72;
lat = -33.1;
# Liberacion en el tiempo
initime = 0
num_steps = 720
time_step = timedelta ( hours =1)
time_step0 = timedelta ( hours =1)
Sembrar elementos
Antes de iniciar la ejecución de un modelo, se deben sembrar (liberar) algunos elementos. El
caso más simple es sembrar un solo elemento en una posición y en un momento determinados.
En este caso lo que se hace es una liberación en un solo punto con un radio de 1500 metros (esto
da aleatoriedad del punto de inicio acotado a un radio de 1500 metros), soltando 100 partı́culas
en cada paso de tiempo (720 horas) a una profundidad de 3 metros.
for i in range ( num_steps +1) :
o . seed_elements ( lon , lat , radius =1500 , number =100 , z = -3 ,
time = time )
9 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
Configuración
OpenDrift permite la configuración del modelo utilizando el paquete ConfigObj. Las
propiedades que se pueden configurar se pueden enumerar mediante el comando
“o.list configspec()’. En este caso se da una instrucción de qué pasará con la partı́cula en
caso de llegar a la costa, es este caso se configurará para que quede varada en la costa (la
particula quedará desactivada y no se moverá de ahı́). OpenDrift admite tres tipos diferentes
de interacción con la costa, los otros dos casos son “previous” que mantiene la partı́cula en la
costa hasta que se muevan mar adentro en un momento posterior y “none” que significa que
no se considerará la costa y la partı́cula seguirá su trayectoria como si no hubiese tierra.
# Varada
o . set_config ( ' general : coastline_action ' , ' stranding ')
Ejecución del modelo
Después de la inicialización, agregar lectores y sembrar elementos, se puede iniciar una ejecución
del modelo (simulación) llamando a la función “o.run()”. La simulación comenzará en el
momento del primer elemento sembrado y continuará hasta el final de cualquiera de los lectores
agregados. El intervalo de tiempo predeterminado es una hora (3600 segundos). El paso de
tiempo de cálculo se puede especificar con el parámetro time step, en segundos. En este caso
obtendremos un archivo de salida NetCDF con 720 pasos de tiempo llamado “1pto.nc”.
# Simulacion
o . run ( time_step =3600 , outfile = '1 pto . nc ')
Graficar y analizar los resultados
Teniendo el archivo NetCDF podremos graficar los resultados en otro código o revisar el estado
de este usando “ncdump”. No obstante, podremos hacerlo directamente desde el entorno donde
estemos trabajando ejecutando el comando “print(o)”. Para graficar un mapa que muestre
las trayectorias usaremos el comando “o.plot()”, en este caso nos guardará un archivo PNG,
considerando que podemos estar trabajando en una terminal. Finalmente “o.animation()”
mostrará una animación de la última ejecución.
o . plot ( filename = '1 pto . png ')
o . animation ( linecolor = 'z ' , fast = True , filename = '1 pto . gif ')
10 Tópicos en Geofı́sica, 7 de octubre de 2021
Capı́tulo 4
Ejemplos de Casos
A continuación se anexarán algunos ejemplos de simulaciones de partı́culas para una entrada
de una archivo ROMS con un mes de simulación de las costas de la quinta región de Valparaı́so,
Chile.
4.1. Un punto inicial
Este caso es el mismo que se explicó paso a paso en el capı́tulo anterior exceptuando que la
interacción con la costa cambió para que la partı́cula que llegue a tierra vuelva posteriormente
al mar. Obtendremos una simulación de 720 pasos horarios, de 100 elementos alrededor de un
punto con un radio de 1500 metros de lejanı́a a este, a una profundidad de 3 metros.
# !/ usr / bin / env python
import matplotlib
matplotlib . use ( ' Agg ')
import sys
sys . path . append ( '/ data1 / tomas / opendrift / ')
import os
from datetime import datetime , timedelta
import numpy as np
from opendrift . readers import reader_ROMS_native
from opendrift . models . oceandrift import OceanDrift
11
Universidad de Concepción Departamento de Geofı́sica
o = OceanDrift ( loglevel =0)
filename_nc = ' quinta2 . nc ';
mosa_native = reader_ROMS_native . Reader ( filename_nc )
mosa_native . interpolation = ' linearND '
o . add_reader ([ mosa_native ])
time = mosa_native . start_time
# Posici ón inicial
lon = -72;
lat = -33.1;
# Liberacion en el tiempo
initime = 0
num_steps = 720
time_step = timedelta ( hours =1)
time_step0 = timedelta ( hours =1)
for i in range ( num_steps +1) :
o . seed_elements ( lon , lat , radius =1500 , number =100 , z = -3 ,
time = time )
# Strading
o . set_config ( ' general : coastline_action ' , ' previous ')
# Simulacion
o . run ( time_step =3600 , outfile = '1 pto . nc ')
o . plot ( filename = '1 pto . png ')
o . animation ( linecolor = 'z ' , fast = True , filename = '1 pto . gif ')
12 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
4.2. Más de un punto inicial
A la configuración de un punto inicial le agregamos dos coordenadas más. Ası́ obtendremos una
simulación de 720 pasos horarios, de 100 elementos alrededor de un tres puntos con un radio
de 1500 metros de lejanı́a a estos, a una profundidad de 3 metros.
# !/ usr / bin / env python
import matplotlib
matplotlib . use ( ' Agg ')
import sys
sys . path . append ( '/ data1 / tomas / opendrift / ')
import os
from datetime import datetime , timedelta
import numpy as np
from opendrift . readers import reader_ROMS_native
from opendrift . models . oceandrift import OceanDrift
o = OceanDrift ( loglevel =0)
filename_nc = ' quinta2 . nc ';
mosa_native = reader_ROMS_native . Reader ( filename_nc )
mosa_native . interpolation = ' linearND '
o . add_reader ([ mosa_native ])
time = mosa_native . start_time
# Posiciones iniciales
lon = -72; lat = -33;
lons = -74; lats = -32.8;
lo = -75; la = -33.1;
# Liberaci ón en el tiempo
initime = 0
num_steps = 720
time_step = timedelta ( hours =1)
time_step0 = timedelta ( hours =1)
13 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
for i in range ( num_steps +1) :
o . seed_elements ( lon , lat , radius = 1500 , number =100 , z = -3 ,
time = time + i * time_step + initime * time_step0 )
o . seed_elements ( lons , lats , radius =1500 , number =100 , z = -3 ,
time = time + i * time_step + initime * time_step0 )
o . seed_elements ( lo , la , radius =1500 , number =100 , z = -3 ,
time = time + i * time_step + initime * time_step0 )
# Strading
o . set_config ( ' general : coastline_action ' , ' previous ')
# Simulacion
o . run ( time_step =3600 , outfile = ' diff_puntos . nc ')
o . plot ( linecolor = 'z ' , fast = True , filename = ' diff_puntos . png ')
o . animation ( filename = ' diff_puntos . gif ')
14 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
4.3. Distintas profundidades
En esta simulación se mantendrá similar a la simulación en un punto. Sin embargo, se definirá
un vector profundidad (z) el cual será aleatorio, por lo tanto la liberación de partı́culas será
aleatoria en la columna de agua en un punto. Notar que en este caso no se puso un radio de
liberación alrededor del punto.
# !/ usr / bin / env python
import matplotlib
matplotlib . use ( ' Agg ')
import sys
sys . path . append ( '/ data1 / tomas / opendrift / ')
import os
from datetime import datetime , timedelta
import numpy as np
# from opendrift . readers import reader_basemap_landmask
from opendrift . readers import reader_ROMS_native
from opendrift . models . oceandrift import OceanDrift
o = OceanDrift ( loglevel =0)
filename_nc = ' quinta2 . nc ';
mosa_native = reader_ROMS_native . Reader ( filename_nc )
mosa_native . interpolation = ' linearND '
o . add_reader ([ mosa_native ])
time = mosa_native . start_time
# Posici ón inicial
lon = -72; lat = -33.1;
# Liberacion en el tiempo
initime = 0
num_steps = 720
time_step = timedelta ( hours =1)
time_step0 = timedelta ( hours =1)
15 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
for i in range ( num_steps +1) :
z = - np . random . rand (2000) *50
o . seed_elements ( lon , lat , z =z , radius =0 , number =2000 ,
time = time + i * time_step + initime * time_step0 )
# Strading
o . set_config ( ' general : coastline_action ' , ' previous ')
# Simulacion
o . run ( time_step =3600 , outfile = ' diff_prof . nc ')
o . plot ( filename = ' diff_prof . png ')
o . animation ( linecolor = 'z ' , fast = True , filename = ' diff_prof . gif ')
16 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
4.4. Cono
Este caso necesita que se importe un reader de un URL. Luego de debe definir el espacio que
abarca el cono (coordenadas iniciales y finales). Ası́, “o.seed.cone” nos permitirá luego definir
el radio de partı́culas del ambos puntos y formará un cono de sedimentación entre ambos. Esto
significa que si ambos radios son iguales se podrı́an hacer figuras cilı́ndricas y experimentar un
poco con eso.
# !/ usr / bin / env python
import matplotlib
matplotlib . use ( ' Agg ')
import sys
sys . path . append ( '/ data1 / tomas / opendrift / ')
import os
from datetime import datetime , timedelta
from opendrift . readers import reader_netCDF_CF_generic
from opendrift . models . openoil import OpenOil
import numpy as np
from opendrift . readers import reader_ROMS_native
from opendrift . models . oceandrift import OceanDrift
o = OceanDrift ( loglevel =0)
o . add_readers_from_list ([
' https :// thredds . met . no / thredds / dodsC / sea / norkyst800m /1 h
/ aggregate_be ' ])
filename_nc = ' quinta2 . nc ';
mosa_native = reader_ROMS_native . Reader ( filename_nc )
mosa_native . interpolation = ' linearND '
o . add_reader ([ mosa_native ])
time = mosa_native . start_time
# Posici ón inicial
17 Tópicos en Geofı́sica, 7 de octubre de 2021
Universidad de Concepción Departamento de Geofı́sica
latstart = -33
lonstart = -72
latend = -32.7
lonend = -73
o . seed_cone ( lon =[ lonstart , lonend ] , lat =[ latstart , latend ] ,
radius =[100 , 800] , number =10000 , time =[ time ])
# Strading
o . set_config ( ' general : coastline_action ' , ' previous ')
# Simulacion
o . run ( time_step =3600 , outfile = ' cone . nc ')
o . plot ( filename = ' cone . png ')
o . animation ( linecolor = 'z ' , fast = True , filename = ' cone . gif ')
18 Tópicos en Geofı́sica, 7 de octubre de 2021
Bibliografı́a
Dagestad, K. F., Röhrs, J., Breivik, Ø., Ådlandsvik, B. (2018). OpenDrift v1. 0: a generic
framework for trajectory modelling. Geoscientific Model Development, 11(4), 1405-1420.
19