OpenDrift / opendrift

Open source framework for ocean trajectory modelling
https://opendrift.github.io
GNU General Public License v2.0
245 stars 120 forks source link

No bathymetry in backward run #1115

Closed MartimBebeagua closed 1 year ago

MartimBebeagua commented 1 year ago

When I run the simulation forward in time everything works as expected, but when I run it backwards, the bathymetry is set to 100 m everywhere. I have no idea what goes wrong, the only change is in the sign of the time_step variable. Any suggestions how to solve this?

I am running version 1.10.7 and I read the Mediterranean bathymetry from a CMEMS file (MED-MFC_006_004_mask_bathy_copy.nc - variable 'sea_floor_depth_below_sea_level').

Thanks, Martin

knutfrode commented 1 year ago

Hi, Is the CMEMS file with bathymetry also covering the time period of your backwards simulation?

MartimBebeagua commented 1 year ago

Hi and thanks! Sadly not. This is a 'static' file with coordinates, mask and bathymetry. There is not time dimension. I am using a copy of the original CMEMS MED-MFC_006_004_mask_bathy.nc file, just that the 'deptho' was renamed to 'sea_floor_depth_below_sea_level' to be recognized by the reader.

MartimBebeagua commented 1 year ago

I also get this error message, which I guess, is connected to interpolation of bathymetry in time?

08:55:44 ERROR   opendrift.models.basemodel:1277: zero-size array to reduction operation minimum which has no identity
Traceback (most recent call last):
  File "/home/martin/opendrift/opendrift/models/basemodel.py", line 1252, in get_environment
    reader.get_variables_interpolated(
  File "/home/martin/opendrift/opendrift/readers/basereader/variables.py", line 842, in get_variables_interpolated
    env, env_profiles = self.get_variables_interpolated_xy(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/martin/opendrift/opendrift/readers/basereader/variables.py", line 708, in get_variables_interpolated_xy
    env, env_profiles = self._get_variables_interpolated_(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/martin/opendrift/opendrift/readers/basereader/structured.py", line 282, in _get_variables_interpolated_
    if (block_before is not None and block_before.covers_positions(
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/martin/opendrift/opendrift/readers/interpolation/structured.py", line 147, in covers_positions
    (y >= self.y.min()) & (y <= self.y.max()))[0]
          ^^^^^^^^^^^^
  File "/home/martin/anaconda3/envs/opendrift/lib/python3.11/site-packages/numpy/core/_methods.py", line 45, in _amin
    return umr_minimum(a, axis, None, out, keepdims, initial, where)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: zero-size array to reduction operation minimum which has no identity

This is the 'sea_floor_depth_below_sea_level' netcdf variable:

float sea_floor_depth_below_sea_level(latitude, longitude) ;
        sea_floor_depth_below_sea_level:_FillValue = 1.e+20f ;
        sea_floor_depth_below_sea_level:long_name = "Bathymetry" ;
        sea_floor_depth_below_sea_level:units = "m" ;
        sea_floor_depth_below_sea_level:standard_name = "sea_floor_depth_below_sea_level"  ;
knutfrode commented 1 year ago

Can you make available this specific file, and some minimum lines of code to reproduce the problem? Then I can have a look at my machine.

MartimBebeagua commented 1 year ago

I uploaded the run scripts to my Dropbox. One is using the OceanDrift model (Run_just_drift.py), while the other is using a customized module which introduces diel vertical migrations for jellyfish simulations:

https://www.dropbox.com/sh/uvli7fuju8c7ow4/AAA8Sm3Gs6ifBCTXgfaUZFkka?dl=0

Thanks a lot!

MartimBebeagua commented 1 year ago

Hi!

I managed to solve the problem. Knut's comment led me to create a bathymetry file with a time dimension using nco. I added 2 time records, one being in 1900 and the other in 2100, so OpenDrift can perform time interpolation.

Here is the code:

# concatenate twice the statics
ncecat -u time MED-MFC_006_004_mask_bathy_copy.nc MED-MFC_006_004_mask_bathy_copy.nc out.nc
# add time values (in days)
ncap2 -O -s 'time[time]={0.0,73049}' out.nc out.nc
# add atribute
ncatted -a units,time,o,c,"days since 1900-01-01" out.nc

cp out.nc MED-MFC_006_004_mask_bathy_1900-2100.nc

Maybe someone will find it useful. Big thanks to Knut for the hint. Cheers! Martin

knutfrode commented 1 year ago

Hi,

I found and fixed a bug related to negative timesteps and readers with no time dimension (as in your case): https://github.com/OpenDrift/opendrift/commit/c8837764c7e7aceb9650b926fbe2fa15695a6c6e

So after updating OpenDrift, your workaround should no longer be necessary.

MartimBebeagua commented 1 year ago

It works with the original file now. Thanks a lot!