Methodology
===========

The ROMS-Tools methodology closely follows the methods employed in the `UCLA MATLAB tools <https://github.com/nmolem/ucla-tools/tree/main>`_.

Grid
#####

A grid can be generated by creating an instance of the :class:`roms_tools.Grid` class:

.. code-block:: python

    from roms_tools import Grid

    grid = Grid(
        nx=100,  # number of points in the x-direction (not including 2 boundary cells on either end)
        ny=100,  # number of points in the y-direction (not including 2 boundary cells on either end)
        size_x=1800,  # size of the domain in the x-direction (in km)
        size_y=2400,  # size of the domain in the y-direction (in km)
        center_lon=-10,  # longitude of the center of the domain
        center_lat=61,  # latitude of the center of the domain
        rot=20,  # rotation of the grid's x-direction from lines of constant longitude, with positive values being a counter-clockwise rotation
    )

To generate the grid, ``ROMS-Tools`` follows a series of steps to define the domain and coordinate system:

- Given the ``size_x`` and ``size_y`` parameters, the domain is initially oriented to prioritize the x-direction as longer than the y-direction. This may involve swapping ``size_x`` with ``size_y`` and ``nx`` with ``ny``. This step is performed to minimize grid distortion.
- ``nx + 2`` grid points are spaced uniformly in longitude.
- A Mercator projection is applied across the equator to convert latitude degrees into y-coordinates. ``ny + 2`` grid points are spaced uniformly in the y-coordinate. An inverse Mercator projection is then performed to return to geographic coordinates.
- If there was a swap in step 1, the grid is now rotated by 90 degrees back to its original orientation.
- The coordinate system is rotated by the specified angle ``rot`` to align with desired orientation.
- Coordinates are translated to center the grid at the specified longitude ``center_lon`` and latitude ``center_lat``.
- Grid metrics ``pm = 1/dx`` and ``pn = 1/dy`` are computed, where ``dx`` and ``dy`` represent the grid spacing in the x and y directions, respectively.
- The angle between the positive x-axis of the local grid and East is computed to establish the orientation relative to geographic directions.

The grid variables are held in an ``xarray.Dataset`` in ``grid.ds``.

Topography
##########

During the grid generation process, ``ROMS-Tools`` also creates a topography field. This is demonstrated in the following example:

.. code-block:: python

    grid = Grid(
        nx=100,
        ny=100,
        size_x=1800,
        size_y=2400,
        center_lon=-10,
        center_lat=61,
        rot=20,
        topography_source="etopo5",  # Data source for the topography (default: 'etopo5')
        smooth_factor=8,  # Smoothing factor for global Gaussian smoothing of the topography (default: 8)
        hmin=5,  # Minimum ocean depth in meters (default: 5)
        rmax=0.2,  # Maximum slope parameter in meters (default: 0.2)
    )

This functionality is executed through the :meth:`roms_tools.Grid.add_topography_and_mask` method, which is automatically called when an instance of the :class:`roms_tools.Grid` class is created.

Users can also directly apply the :meth:`roms_tools.Grid.add_topography_and_mask` method if they wish to overwrite an existing topography or if a grid has been loaded from a file that lacks a topography field. For more detailed information and examples, please refer to `this example <grid.ipynb>`_.

The :meth:`roms_tools.Grid.add_topography_and_mask` method completes four steps:

1. The specified topography file is interpolated onto the ROMS grid.
2. To avoid grid-scale instabilities, the topography is smoothed over the entire domain.
3. Enclosed basins are filled with land.
4. Regions where the ocean depth is shallower than ``hmin`` are set to ``hmin``. The topography is then smoothed locally to satisfy ``r < rmax``. This step modifies the topography predominantly along the continental shelf.

Here are the four steps illustrated for an example domain:

.. image:: images/Step1.png
   :width: 390
.. image:: images/Step2.png
   :width: 390
.. image:: images/Step3.png
   :width: 390
.. image:: images/Step4.png
   :width: 390

After the four steps are completed, the following variables are added to ``grid.ds``:

- ``hraw``: the topography field after step 2
- ``mask_rho``: the wet mask after step 3, obtained by finding the locations where ``hraw > 0`` and then filling in the enclosed basins
- ``h``: the final bathymetry after step 4

Tidal Forcing
##############

Coming soon...


Atmospheric Forcing
####################

Coming soon...
