FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
MarEnv

Calculations pertaining to marine environment processes and properties, such as waves, wind, seafloor and ocean currents. Particularly aimed at facilitating synchronised environment representations between models within distributed simulations.

Contents

What is this?

When simulation models depending on a marine environment are distributed between multiple computers, several issues arise. Most notably, how can one keep time dependent processes, such as wave patterns, synchronised between exchange of information between models? This library seeks to solve this challenge by implementing predefined and deterministic environment models. This implementation includes methods for querying e.g. particle velocities, surface elevation for a given time and position. The main idea is that the environment is specified in terms of constant or slowly varying definitions, which the models feed their local marenv instance. Subsequent queries for e.g. particle velocities will then give the same results in the different models, without requiring further communication. These queries will then be valid and in sync until the environment is changed.

The implementation includes smooth transitions between environment states via output-level cross-fading, ensuring continuity even at large time and position values.

Features

  • [x] Few dependencies
  • [x] Open source and permissive license
  • [x] Synchronised environment states between models
  • [x] Wave models:
    • [x] Linear waves (Airy theory)
    • [x] Gerstner waves
    • [x] Transition between seastates
  • [x] Effects on the environment from models (static wakes only).
  • [x] Bathymetry
  • [ ] Seafloor forces
  • [ ] Wind

Why should I use this?

The aim is for this implementation to be easy to use, with as few dependencies as possible and open source. It aims at providing a standard for the handling of marine environments in distributed simulations, but it should be well suited for use in other situations where marine environment calculations are needed. To support synchronised environments between computers and processes, a pseudorandom number generator is implemented.

Using the library

Marenv provides a single API to query marine environmental conditions through a single interface. The implementation behind this interface aims to be interchangeable, giving the user the ability to query environmental data, such as waves, currents, and seafloor data through a unified interface.

Conan is the preferred way of using this library. The package is usually consumed using the conan install command or a conanfile.txt.

  1. Add remote to conan's package remotes:

    conan remote add sintef-public https://gitlab.sintef.no/api/v4/projects/22218/packages/conan
  2. Using conanfile.txt in your project with cmake

    Add conanfile.txt:

    [requires]
    marenv/[>=0.0.1]@sintef/stable
    [options]
    marenv/*:shared=False # default
    marenv/*:with_doc=True # default
    [generators]
    CMakeDeps
    CMakeToolchain

    Insert into your CMakeLists.txt something like the following lines:

    cmake_minimum_required(VERSION 3.15)
    project(TheProject CXX)
    find_package(marenv CONFIG REQUIRED)
    add_executable(the_executor code.cpp)
    target_link_libraries(the_executor marenv::marenv)

    Install and build:

    conan install . -s build_type=<build_type> -pr:b=default

    where <build_type> is e.g. Debug or Release. You can now continue with the usual cmake commands for configuration and compilation, provided that you point to the toolchain file when running the cmake commands. For details on how to use conan, please consult Conan.io docs

Fields and their implementations

Marenv aims to provide a full set of interfaces, and a minimum set of implementations. This allows for proprietary implementations being used without its source code. Currently, the emphasis is placed on linear wave models. These create sea states by superpositioning of multiple wave components. There are three implementations:

  • AiryWavesScalar implements the airy wave theory. This implementation favors few wave components.
  • AiryWaves implements the airy wave theory using SIMD (Single Instruction Multiple Data). This implementation is more efficient for many wave components.
  • GerstnerWaves implements Gerstner wave theory. These waves are more accurate, but they are also more computational demanding.

The seafloor implementation defines the depths as a combination of harmonic variations.

There are three implementations of ocean currents:

  • ConstantCurrent defines a current independent of time and position.
  • DepthVaryingCurrent defines a current varying with depth only.
  • DepthVaryingCurrentField defines a current varying with both depth and position.

Basic Usage Example

#include <marenv/EnvironmentFacade.h>
#include <marenv/current/ConstantCurrent.h>
#include <marenv/seafloor/BathymetryWaves.h>
#include <marenv/wave/WaveComponents.h>
#include <marenv/wave/WaveEnergySpectrum.h>
int main()
{
// Waves
p.Hs = 2;
p.T1 = 8;
p.Theta = 0.3;
p.cosinePower = 1;
p.omegaNDimLowLim = 0.1;
p.omegaNDimUppLim = 5;
p.spectrumType = marenv::wave::SpectrumType::JONSWAP;
int numWaves = 13;
uint32_t randomSeed = 4;
/* If the wave model is to be used directly, it can be created like this and optionally passed to the environment facade:
auto waves = std::make_shared<marenv::wave::AiryWaves>(p, numWaves, randomSeed);
auto env = marenv::EnvironmentFacade();
env.SetWaves(waves);
*/
// Seafloor
double averageDepth = 200.0;
int numComponents = 5;
double sumAmplitudes = 5.0;
double minWavelength = 1.0;
double maxWavelength = 20.0;
auto bathymetry = std::make_shared<marenv::seafloor::BathymetryWaves>(averageDepth, numComponents, sumAmplitudes, minWavelength, maxWavelength, randomSeed);
// Ocean currents
double currentSpeed = 1.0;
double currentDir = marenv::PI * 90.0 / 180.0;
auto currents = std::make_shared<marenv::current::ConstantCurrent>(currentSpeed, currentDir);
// Environment facade
env.SetWaves(p, marenv::wave::WaveTheory::Airy, numWaves, randomSeed);
env.SetBathymetry(bathymetry);
env.AddCurrentField("primary", currents);
// Querying wave specification
auto waves = env.GetWaves();
auto waveComponents = waves->GetWaveComponentsCopy();
auto firstWaveAmplitude = waveComponents.zetaA[0];
// Querying environment
double pos[3] = {0.0, 0.0, 4.0};
double pressure;
double elevation;
double currentVelocity[3];
double depth;
double seabedDensity;
marenv::Status status = marenv::Status::OK;
for (double t = 0.0; t < 10.0; t += 0.1) {
status &= env.GetDynamicPressure(t, pos, pressure);
status &= env.GetSurfaceElevation(t, pos, elevation);
status &= env.PointEnvironmentQuery(t, pos, query);
status &= env.GetCurrentVelocity(t, pos, currentVelocity);
status &= env.GetSeaDepth(pos, depth);
status &= env.GetSeabedRho(pos, seabedDensity);
}
if (status == marenv::Status::OK) return 0;
return 1;
}
Definition EnvironmentFacade.h:29
@ EqualSqrtEnergy
Each wave component has the same .
@ Sequential
Higher energies in main direction.
Status
Definition marenv.h:40
@ Airy
Linear wave theory (Airy waves). SIMD-optimized for many wave components, computationally efficient.
constexpr double PI
Defines pi.
Definition marenv.h:18
Struct for containing the data for a environment query.
Definition Environment.h:25
The parameters defining a certain wave field.
Definition WaveEnergySpectrum.h:41

Coordinate system, directions and units

This library uses a right-handed coordinate system with the x-axis pointing East, the y-axis pointing North and the z-axis pointing Down. Depths are therefore positive below mean sea level. Note that the wave elevation is positive upwards. Wave elevation is not the z-position of the surface, but rather the local elevation of the surface.

The units used are SI units if nothing else is obvious from the naming of variables or functions.

Key Functions

Method Description
GetSurfaceElevation() Returns free-surface elevation (η).
GetParticleVelocity() Returns total particle velocity (waves + currents).
GetPressure() Returns dynamic pressure at depth.
GetSeadepth() Returns seafloor depth at a position.
PointEnvironmentQuery() Returns multiple quantities in one call.

Return Codes

All functions return a status from the Status enum:

Code Meaning
Status::OK Operation successful.
Status::OUT_OF_RANGE_INACCURATE Query outside valid range — returned value may be approximate.
Status::NOT_APPLICABLE_NOT_SET Data not applicable or not configured.
Status::ERROR_NOT_SET Operation failed, no valid data available.
Status::NOT_IMPLEMENTED Function not yet implemented.

Developing the library

Building this repository locally can be done with conan using the following commands.

  1. To build into subfolder folder of repository (marenv).

    cd marenv
    conan build . -o marenv/*:with_doc=False -c tools.build:skip_test=True -b missing

    This builds the library without doc and tests into build (Windows) or build/<build_type> (Linux). Subsequent builds can be done using cmake commands.

  2. To create a package in the local conan cache.

    cd marenv
    conan create . --user sintef --channel marenv -b missing -o marenv/*:shared=False

Building Documentation

Documentation is built with Doxygen and the doxygen-awesome-css theme:

cmake -S . -B build/Release -DCMAKE_BUILD_TYPE=Release -DMARENV_WITH_DOC=ON
cmake --build build/Release --target doc
# Open build/Release/doc/html/index.html

Package options

Option Allowed values Default value
shared [True, False] False
fPIC [True, False] True
with_doc [True, False] True

Code overview

The marenv:: namespace defines abstract interfaces and a composite architecture for modeling and querying marine environment data. Each physical aspect of the environment is represented by a dedicated interface:

Field Purpose
**WaveField** Computes wave-induced quantities (e.g., surface elevation, velocities, pressures).
**CurrentField** Provides current velocity fields.
**BathymetryField** Represents seafloor geometry and material properties.
**Environment** Unified interface combining waves, currents, and bathymetry.
**EnvironmentFacade** Concrete class delegating calls to individual sub-fields.

Directory Structure

The most important part of the directory structure is shown below. The marenv/include/marenv directory contains the public API of the project.

marenv
├── include
│   └── marenv
│   ├── calc
│   ├── current
│   ├── seafloor
│   └── wave
├── src
│   ├── calc
│   ├── current
│   ├── seafloor
│   └── wave

Contribute

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate.

  • Each new environment model should implement the relevant interface.
  • Always return an appropriate Status value to indicate query validity.
  • Use smart pointers (std::shared_ptr) for shared ownership.
  • Extend Environment when combining additional phenomena (e.g., temperature, salinity).

License

MIT