C++ library, with python bindings, to provide random access to large ocean model data sets. Primarily intended for use with autonomous underwater vehicle simulations.
- FVCOM
- General Rectilinear Gridded Model /w Sigma Layers
- Miscellaneous primitive "models"
The coordinate system type can be set with the ModelInterface::setCoordinateType() function. The lat/lon origin should also be set with the ModelInterface::setOrigin() function. The two available options at XY (meters) and LATLON. The model implementation should correctly handle both XY and LATLON options. The ModelInterface::getData(double, double, double, double) and ModelInterface::getDataOutOfRange(double, double, double, double) by default assume that the underlying model uses an XY coordinate system, but they should be override if needed (see GeodeticGrid for an example of this). Z+ should always be up, with 0 at the sea surface. If a loaded model is different from this, then the model implementation should handle to accept the correct Z axis direction. If a model has a free-surface, Z=0 should be the mean sea surface, not the free-surface. This ensures a constant, non-moving reference frame.
Future work is to create a general method of allowing a model to be queried in an arbitrary CRS and have that converted to the correct CRS for the specific loaded model.
When using the coordainte type of LATLON the x and y parameters for ModelInterface::getData(double, double, double, double) and ModelInterface::getDataOutOfRange(double, double, double, double) should be set as follows: x=lon, y=lat.
See the FVCOM Website for more information on the model itself. Below is a summary of our implementation to provide quick random access to the FVCOM model.
Due to the size of FVCOM models it is not feasible to load the entire model into memory. Instead we only load the general structure of the model into memory, without the variable data. When a specific location and time is queried, a section, or "chunk", of the model containing that data will be loaded. These chunks are then stored in an LRU Cache. The size of these chunks and the cache size can be specified by the user.
Linear interpolation in the temporal and z dimensions are performed for all data variables. For the x and y dimensions, barycentric linear interpolation of the variables located at the nodes (temp, salt, etc.) is performed. For variables located at triangle centers (u,v,w, etc.), interpolation in the x and y dimensions is simply determined based on the containing triangle, similar, although not exactly, like nearest neighbors.
This limitation in the x and y dimension for variables located at triangle centers at is due to the unstructured nature of FVCOM. Triangulation at these points would be required to do baricentric linear interpolation. This is not too difficult of a task, but has yet to be implemented. This limitation does not exist with variables at nodes as the FVCOM structure already provides a triangulation.
- To simplify depth calculations and interpolation, the
center_handcenter_siglayFVCOM variables are ignored.center_handcenter_siglaycorrespond to the water column height and percent depth for each siglay at the center of each triangle. Instead we use barycentric interpolation of the nodes that form each triangle to determine the depth of a specific siglay for points inside of that triangle. This can theoretically lead to the edge case where a queried location is below the true model bathemetry (i.e. belowcenter_hat the triangle center), but above the interpolated bathemetry that we use to determine depth. In this case the data from the lowest depth siglay is used. In practice this would require a significant difference between the interpolated depth at a triangle center and the depth stored incenter_h. - We currently assume the values of the
hFVCOM variable are positive and the values of thesiglayFVCOM variable are negative. - Currently the data retrieved for a given location is the standard u,v,w,temp,salt,depth as well as an additional optional dye variable. It is not currently possible to load other arbitrary data variables.
See unit tests at ocean_model_interfaces/test/FVCOM_test.cpp
Generally, only the FVCOM class needs to be used directly. Although, in unique cases or debugging purposes the FVCOMStructure class could be useful.
This model is a generalized rectilinear geodetic (lat,lon) gridded model with sigma vertical layers. This can be used for either models that are native to a geodetic grid or can be easily converted into one such as ROMS. Similar to the FVCOM models, it is assumed that the geodetic grid models are too large to load into memory at once, so only the general structure is loaded and data is loaded on demand in chunks and stored in an LRU cache.
Linear interpolation is done in all four dimensions. This is done by projecting the relevant lat/lon values needed for interpolation only a local XY grid and interpolating on that XY grid.
- Fixed water column depth
- No free-surface (i.e. depth of data points are constant in time)
- North aligned lat/lon grid
- Pre-processed model data that includes the point depths in the file, instead of just the sigma layer information.
An example of using this model type can be found in scripts/geodetic_grid_plotting_example.ipynb
The script scripts/roms_model_regularization.py should be used to regularize a ROMS model to fit the assumptions above. ROMS by default is not neseccarily north aligned, data points are on a C-Grid, and it can have a free-surface, so it needs to be regularized to fit the General Geodetic Gridded Model /w Sigma Layers. This script will check that the model is north aligned and interpolate all points from the C-grid to a lat/lon grid.
These models provide a primitive, non-realistic models that are useful for simple testing, debugging, and sanity checking.
Current Primitive Models:
- ConstantModel
- LinearModel
- OceanFrontModel
Examples for the OceanFrontModel can be found in the unit tests at ocean_model_interfaces/test/OceanFrontModel_test.cpp. The others are fairly self-explainatory.
cd ocean_model_interfaces
mkdir build
cd build
To install in default libary directory
cmake ../src
To install in specific location
cmake ../src -DCMAKE_INSTALL_PREFIX:PATH=<install_path>
make
make install
Enable the BUILD_TESTING cmake option
cd ocean_model_interfaces/build
make
make test
Use the following for verbose output of the tests
make test CTEST_OUTPUT_ON_FAILURE=TRUE
Enable the BUILD_DOCS cmake option
cd ocean_model_interfaces/build
make
Documentation is output to build/ocean_model_interfaces/doc/doc_doxygen
sudo apt-get install libboost-system-dev libboost-filesystem-dev
sudo apt-get install libhdf5-dev libcurl4-gnutls-dev
Get latest version of NetCDF-C from https://www.unidata.ucar.edu/downloads/netcdf
Untar and cd into directory
mkdir build
cd ./build
cmake ../ -DCMAKE_BUILD_TYPE=RELEASE
sudo make install
Get latest version of NetCDF-4 C++ from https://www.unidata.ucar.edu/downloads/netcdf
Untar and cd into directory
mkdir build
cd ./build
cmake ../ -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_C_FLAGS=-I/usr/include/hdf5/serial/
sudo make install
When using cmake:
find_package(OceanModelInterfaces)
target_link_libraries(<target_name> PRIVATE|PUBLIC|INTERFACE OceanModelInterfaces::ocean_model_interfaces)
When not using cmake link to the ocean_model_interfaces library in the standard way.
Copyright 2026, by the California Institute of Technology. ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged. Any commercial use must be negotiated with the Office of Technology Transfer at the California Institute of Technology.
Andrew Branch - [email protected]