Skip to content

Conversation

@oddvarlia
Copy link
Collaborator

@oddvarlia oddvarlia commented Dec 6, 2025

Function to update 3D field parameters with the method implemented in DistanceESMDA for ensemble smoother with
distance-based localization

Linked to: #12406

Approach
A 3D field parameter can often not be update in one go due to large memory requirements due to the Kalman gain matrix K and the localization matrix RHO. To handle this the field parameter can be split into subsets or batches. Each batch should be a set of layers of field parameter values defined in the field parameter grid (ertbox grid). Each batch must consists of a complete set of layers, not subset of layers of field parameters. The main reason for processing the update by batches of layers of field parameters is that the calculation of scaling factors (elements in the RHO matrix) can be done layer by layer due to the assumption that only lateral distance is of importance in the definition of influence of an observation, hence the calculation of RHO is done for one layer and then copied to all the other layers of the ertbox grid.

@oddvarlia oddvarlia marked this pull request as draft December 6, 2025 10:16
@oddvarlia oddvarlia changed the title Added function to update 3D field parameter with ensemble smoother wi… Update 3D field parameter with ensemble smoother with distance-based localization Dec 6, 2025
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 2 times, most recently from 1554bb7 to 36554db Compare December 6, 2025 19:50
@codecov-commenter
Copy link

codecov-commenter commented Dec 6, 2025

Codecov Report

❌ Patch coverage is 94.11765% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.67%. Comparing base (c528c39) to head (0587269).

Files with missing lines Patch % Lines
src/ert/analysis/_es_update.py 93.49% 16 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12469      +/-   ##
==========================================
- Coverage   90.67%   90.67%   -0.01%     
==========================================
  Files         429      429              
  Lines       29803    30073     +270     
==========================================
+ Hits        27025    27268     +243     
- Misses       2778     2805      +27     
Flag Coverage Δ
cli-tests 37.24% <6.98%> (-0.33%) ⬇️
gui-tests 68.70% <6.98%> (-0.71%) ⬇️
performance-and-unit-tests 74.09% <94.11%> (+0.16%) ⬆️
test 37.79% <6.98%> (-0.29%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@xjules xjules added this to SCOUT Dec 8, 2025
@xjules xjules moved this to In Progress in SCOUT Dec 8, 2025
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 9 times, most recently from b52aa01 to a9c9709 Compare December 12, 2025 10:10
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 4 times, most recently from 568900f to 3d044e4 Compare December 20, 2025 09:49
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 7 times, most recently from e4b0c6f to 8f14437 Compare January 6, 2026 18:46
@oddvarlia oddvarlia removed the status in SCOUT Jan 7, 2026
@oddvarlia oddvarlia moved this to In Progress in SCOUT Jan 7, 2026
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch from 8f14437 to 9f42875 Compare January 7, 2026 12:26
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 12 times, most recently from 799157d to 5471426 Compare January 16, 2026 09:45
@codspeed-hq
Copy link

codspeed-hq bot commented Jan 16, 2026

Merging this PR will not alter performance

✅ 22 untouched benchmarks


Comparing oddvarlia:distance_based_batch_update (0587269) with main (c528c39)

Open in CodSpeed

@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 3 times, most recently from 0bd1029 to a464ab2 Compare January 19, 2026 11:06
@oddvarlia oddvarlia moved this from In Progress to Ready for Review in SCOUT Jan 19, 2026
@oddvarlia oddvarlia requested a review from xjules January 19, 2026 11:54
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch from 999445a to 01ed347 Compare January 19, 2026 12:00
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch 2 times, most recently from 4ee2df8 to 69bf521 Compare January 20, 2026 08:40
… 3D fields

Added functions:
- update_3D_field_with_distance_esmda
- _calc_max_number_of_layers_per_batch_for_distance_localization

The function 'update_3D_field_with_distance_esmda' will update one 3D field parameter
(or 2D field parameter when nz = 1) using the algorithm implemented in class DistanceESMDA
in repo iterative_ensemble_smoother. This function requires that
an object of DistanceESMDA is input.
It will split the field parameter in batches when necessary due to memory
constraints.

The function '_calc_max_number_of_layers_per_batch_for_distance_localization' calculates the max
size of a batch of field parameter values within the limit of available memory.

update pyproject.toml  to include gaussianfft to be used in tests
@oddvarlia oddvarlia force-pushed the distance_based_batch_update branch from 69bf521 to 6b1d6e2 Compare January 20, 2026 11:28
)


def calc_max_number_of_layers_per_batch_for_distance_localization(
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe as an inspiration you can have a look at def _calculate_adaptive_batch_size ?

X_prior_3D = X_prior.reshape(nx, ny, nz, nreal)
# No update if no observations or responses
if Y is None or Y.shape[0] == 0:
# No update of the field parameters
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can just return X_prior, yes.

Copy link
Contributor

Choose a reason for hiding this comment

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

you can also remove the comments, but keep the one above. # No update if no observations or responses

)
) # Use float64
nlayer_per_batch = min(max_nlayers_per_batch, nz)
nbatch = int(nz / nlayer_per_batch)
Copy link
Contributor

Choose a reason for hiding this comment

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

if nz==10 and nlayer_per_batch==7 then nbach = 1, is this correct?

nlayer_per_batch = min(max_nlayers_per_batch, nz)
nbatch = int(nz / nlayer_per_batch)

log_msg = "Minimum number of batches required due to "
Copy link
Contributor

Choose a reason for hiding this comment

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

we can log nbatch and nlayer_per_batch and make the message concise

Comment on lines +739 to +743
log_msg = (
f"Batch number: {batch_number}\n"
f"start layer : {start_layer_number}\n"
f"end layer : {end_layer_number - 1}"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

remove the logs.



@memory_usage_decorator(enabled=False)
def update_3D_field_with_distance_esmda(
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's double-check if iterative-ensemble-smoother would be a better place to host this code.

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

Labels

None yet

Projects

Status: Ready for Review

Development

Successfully merging this pull request may close these issues.

3 participants