Deltares / Deltares/imod-python

[FEATURE] - Improvements to ``imod.prepare.cleanup_wel``

Open
#1,398 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
41
Forks
12
Avg merge
21h 8m
Merged PRs (30d)
1

Description

Situation

Wells can be located at unsuitable locations in our model:

  1. Above surface level
  2. In aquitards (layers with very low transmissivity)
  3. Below the model base

We need functionality to detect and handle these situations, with options for different handling strategies.

Summary discussion

I had a discussion with @Huite about this, summary:

  • The need for this functionality emerged from a discussion about handling problematic well locations. Key points discussed:
  • Different categories of issues (above surface, in aquitards, below base) should probably be handled differently by default
  • For wells above surface and below base, location limits are clearly defined by model top/bottom
  • For aquitards, a transmissivity threshold is needed to identify problematic layers
  • When using "nearest" fix strategy, wells might not find a suitable layer (e.g., if entire column has low transmissivity)

Concluded that users should have control over:

  • How each type of issue is handled (drop/adjust/ignore)
  • How to handle remaining issues after fixes (raise/warn/ignore)

Behaviour present code base

cleanup_wel currently handles case 1. by adjusting filter location. Case 3. is handled by adjusted if filter is still overlapping with the bottom layer, but dropped if entirely blow model base.

Case 2. is handled when calling Well.to_mf6_pkg and it meets the criteria of either minimum_thickness or minimum_k.

We'd like more control over behaviour and this cleanup in one place.

Requirements

The well cleanup should handle three categories of issues:
Location issues

  1. above_surface: Well (partially) above surface level
  2. in_aquitard: Well in layer with transmissivity below threshold
  3. below_base: Well (partially) below model base

Fix strategies
For each issue, users should be able to choose:

  • "drop": Remove problematic wells
  • "nearest": Move well to nearest valid location
  • No fix (leave as-is)

Validation modes
Users should be able to control how remaining issues are handled:

  • "raise": Raise error if issues remain after fixes
  • "warn": Warn if issues remain after fixes
  • "ignore": Ignore remaining issues

Proposed API

We were still discussing whether to use an OO approach, or prefer functions:

Object Oriented

wells_cleanup = imod.WellCleanup(wells, top, bottom, k)
well_cleanup.adjust_above_surface("drop")      # Drop wells above surface 
well_cleanup.adjust_in_aquitard("nearest")     # Move wells in aquitards to nearest valid layer
well_cleanup.adjust_below_base("drop")         # Drop wells below base 
cleaned_wells = well_cleanup.validate("warn")  # Warn about any remaining issues

Functions

def cleanup_wells(
    wells: pd.DataFrame,
    top: GridDataArray,
    bottom: GridDataArray,
    hydraulic_conductivity: GridDataArray,
    minimum_thickness: float = 0.05,
    minimum_transmissivity: float = 0.1,
    validation_mode: Literal["raise", "warn", "ignore"] = "raise",
    above_surface: Literal["drop", "adjust_nearest", None] = "adjust_nearest",
    in_aquitard: Literal["drop", "adjust_nearest", None] = "adjust_nearest", 
    below_base: Literal["drop", "adjust_nearest", None] = "drop",
) -> pd.DataFrame:
...

I think because we are dealing with data transformations, a function oriented approach is preferable here, as it is easier for debug in an interactive session (IPython/Jupyter), which how most of our users are using iMOD Python.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with imod.prepare.cleanup_wel and the existing Well.to_mf6_pkg behavior described in the issue. Decide on the function-oriented API, then ensure cleanup covers above-surface, aquitard, and below-base wells with configurable fixes and validation modes; done means remaining issues follow the selected raise, warn, or ignore behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design, data
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.