sandialabs / WecOptTool

WEC Design Optimization Toolbox
https://sandialabs.github.io/WecOptTool/
GNU General Public License v3.0
12 stars 20 forks source link

Wave from empirical data is tricky #316

Closed ryancoe closed 2 months ago

ryancoe commented 5 months ago

I was trying to use wot.waves.long_crested_wave to create a wave based on an empirical spectrum. In the docstring for wot.waves.long_crested_wave it says you should pass an Omnidirection wave spectrum in units of m^2/Hz, in the format used by :py:class:wavespectra.SpecArray.

https://github.com/sandialabs/WecOptTool/blob/598e875cd48751ddb652657391205f6e208714f0/wecopttool/waves.py#L197-L227

So I did something like the following:

import numpy as np
import xarray as xr
import wavespectra
import wecopttool as wot

efth = np.array([0.00000000e+00, 0.00000000e+00, 1.09429785e-03, 5.89094920e-02,
                 2.07249055e-01, 2.02675843e-01, 1.68867998e-01, 1.19803351e-01,
                 7.78674098e-02, 4.96642804e-02, 3.23615943e-02, 2.09029418e-02,
                 1.36226413e-02, 8.86459619e-03, 5.62541522e-03, 3.37224324e-03,
                 2.02762403e-03, 1.13507449e-03, 4.59939791e-04, 2.04417576e-04,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
                 0.00000000e+00, 0.00000000e+00, 0.00000000e+00])
freq = np.array([0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225,
                 0.25, 0.275, 0.3, 0.325, 0.35, 0.375, 0.4, 0.425, 0.45,
                 0.475, 0.5, 0.525, 0.55, 0.575, 0.6, 0.625, 0.65, 0.675,
                 0.7, 0.725, 0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9,
                 0.925, 0.95, 0.975, 1., 1.025, 1.05, 1.075, 1.1, 1.125,
                 1.15, 1.175, 1.2, 1.225, 1.25, 1.275, 1.3, 1.325, 1.35,
                 1.375, 1.4, 1.425, 1.45, 1.475, 1.5, 1.525, 1.55, 1.575,
                 1.6, 1.625, 1.65, 1.675, 1.7, 1.725, 1.75, 1.775, 1.8,
                 1.825, 1.85, 1.875])
da = xr.DataArray(data=np.transpose(np.atleast_2d(efth)),
             dims=[
                 "freq",
                 "dir"
                 ],
             coords=dict(
                 freq=freq,
                 dir=[0],
                 ),
             )
ws = wavespectra.SpecArray(da)
wot.waves.long_crested_wave(efth=ws)

This produces an error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[20], [line 41](vscode-notebook-cell:?execution_count=20&line=41)
     [29](vscode-notebook-cell:?execution_count=20&line=29) da = xr.DataArray(data=np.transpose(np.atleast_2d(efth)),
     [30](vscode-notebook-cell:?execution_count=20&line=30)              dims=[
     [31](vscode-notebook-cell:?execution_count=20&line=31)                  "freq",
   (...)
     [37](vscode-notebook-cell:?execution_count=20&line=37)                  ),
     [38](vscode-notebook-cell:?execution_count=20&line=38)              )
     [39](vscode-notebook-cell:?execution_count=20&line=39) ws = wavespectra.SpecArray(da)
---> [41](vscode-notebook-cell:?execution_count=20&line=41) wot.waves.long_crested_wave(efth=ws)
     [42](vscode-notebook-cell:?execution_count=20&line=42) ws

File [~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:215](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:215), in long_crested_wave(efth, direction, seed)
    [212](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:212) f1, nfreq = frequency_parameters(efth.freq.values, False)
    [213](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:213) df = f1
--> [215](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:215) values = efth.values
    [216](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:216) values[values<0] = np.nan
    [217](https://file+.vscode-resource.vscode-cdn.net/Users/rcoe/Downloads/~/mambaforge/envs/wot_release/lib/python3.11/site-packages/wecopttool/waves.py:217) amplitudes = np.sqrt(2 * values * df)

AttributeError: 'SpecArray' object has no attribute 'values'

I was able to resolve the problem by doing just passing my raw xr.DataArray (not the wavespectra.SpecArray):

# continuing from above
wot.waves.long_crested_wave(da)

This is OK I guess, but if so our docstring is misleading.

Suggested options:

  1. Update the docstring for wot.waves.long_crested_wave to make it clear that you should pass a xr.DataArray with a specific structure (don't love this one)
  2. Update the source for wot.waves.long_crested_wave to use a wavespectra.SpecArray as the input argument (preferred)
ryancoe commented 3 months ago

Note that this is somewhat related: https://github.com/wavespectra/wavespectra/issues/107

ryancoe commented 3 months ago

Note that we should make sure any changes to close this issues are consistent across:

It may also make sense to combine these functions, as long_crested_wave is just a special case of irregular_wave, right?

cmichelenstrofer commented 2 months ago

closed by #326