Skip to content

Add vector_fields parameter to FieldSet creation methods#2715

Open
VeckoTheGecko wants to merge 20 commits into
Parcels-code:mainfrom
VeckoTheGecko:push-tsuxxvzqtmup
Open

Add vector_fields parameter to FieldSet creation methods#2715
VeckoTheGecko wants to merge 20 commits into
Parcels-code:mainfrom
VeckoTheGecko:push-tsuxxvzqtmup

Conversation

@VeckoTheGecko

@VeckoTheGecko VeckoTheGecko commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a vector_fields parameter which allows users to control vector fields that are created.

Looking at the following tests you can see how they're used

def test_fieldset_structured_vectorfield_default():
    ds = datasets_structured["ds_2d_left"][["U_A_grid", "V_A_grid", "grid"]].rename({"U_A_grid": "U", "V_A_grid": "V"})

    fset = FieldSet.from_sgrid_conventions(ds, mesh="flat")

    assert "U" in fset.fields
    assert "V" in fset.fields
    assert "UV" in fset.fields


def test_fieldset_structured_vectorfield_custom():
    ds = datasets_structured["ds_2d_left"][["U_A_grid", "V_A_grid", "grid"]].rename({"U_A_grid": "U", "V_A_grid": "V"})
    ds = ds.rename({"U": "U_wind", "V": "V_wind"})

    fset = FieldSet.from_sgrid_conventions(ds, mesh="flat", vector_fields={"UV_wind": ("U_wind", "V_wind")})

    assert "U_wind" in fset.fields
    assert "V_wind" in fset.fields
    assert "UV_wind" in fset.fields


def test_fieldset_structured_vectorfield_none():
    ds = datasets_structured["ds_2d_left"][["U_A_grid", "V_A_grid", "grid"]].rename({"U_A_grid": "U", "V_A_grid": "V"})

    fset = FieldSet.from_sgrid_conventions(ds, mesh="flat", vector_fields=None)

    assert "U" in fset.fields
    assert "V" in fset.fields
    assert "UV" not in fset.fields

Now users can:

  • specify the names of vectorfields and their components
  • explicitly set that no vector fields are created (by doing vector_fields = {} or vector_fields = None)

If vector_fields is not provided it uses the default behaviour of constructing UV and UVW if the component fields are present.

These changes have also been added to the unstructured grid side as well.

Checklist

AI Disclosure

  • This PR contains AI-generated content.
    • I have tested any AI-generated content in my PR.
    • I take responsibility for any AI-generated content in my PR.
    • Describe how you used it (e.g., by pasting your prompt): only for updating the docstring

Comment thread src/parcels/_core/fieldset.py Outdated
cls,
ds: ux.UxDataset,
mesh: str = "spherical",
vector_fields: TVectorFieldMapping | None | NotSetType = NOTSET,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTSET here is an example of a "sentinel value".

They're handy in the case of wanting to distinguish between None and "the default behaviour"

in our case here we want vector_fields=None to mean no vector fields, and the default behaviour to autodiscover based on if there are U and V fields.

@erikvansebille erikvansebille left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this quick PR! See below some comments

Comment thread src/parcels/_core/fieldset.py Outdated
Comment thread src/parcels/_core/model.py Outdated
Comment thread src/parcels/_core/fieldset.py Outdated
Comment thread src/parcels/_core/fieldset.py Outdated
Comment thread src/parcels/_core/model.py Outdated
Comment thread src/parcels/_core/model.py
Comment thread src/parcels/_core/model.py Outdated
Comment thread src/parcels/_python.py
V = TypeVar("V")

NotSetType = enum.Enum("NotSetType", "VALUE")
NOTSET = NotSetType.VALUE

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but would there be a benefit in also using this NOTSET when postponing setting the particle.time?

if time is None or len(time) == 0:
# do not set a time yet (because sign_dt not known)
time = np.array(np.nan)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure what you mean by this. Do you mean to use NOTSET instead of None for the time parameter in the init of the particleset?

Comment thread tests/test_fieldset.py
Now also has vectorfields
@VeckoTheGecko

Copy link
Copy Markdown
Contributor Author

All feedback has been addressed - ready for re-review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Decide on API for defining VectorFields

2 participants