MetOffice / MetOffice/lfric_apps

Incorrect adjoint semi-implicit timestep when reference_reset_time != dt

Open
#87 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Fortran
Stars
31
Forks
118
Avg merge
2d 4h
Merged PRs (30d)
8

Description

### Version

main

### Are there any linked Issues or Pull Requests?

https://code.metoffice.gov.uk/trac/lfric_apps/ticket/988, #84, #85

### What happened?

Currently, the linear and adjoint forecast models, when run via `jedi_lfric_tests` and `JEDI`, fail an adjoint test if `reference_reset_time != dt`, meaning the adjoint is incorrect in this case.

We want to be able to `set reference_reset_time` as a multiple of `dt` so as to closer match the `lfric_atm` configuration.

To explain by way of example:
- At the start of `tl_semi_implicit_alg_step` _and it's adjoint_, there is the following conditional block (slightly simplified here):

```
reference_reset_freq = reference_reset_time / dt
if ( mod( modeldb%clock%get_step() - 1, reference_reset_freq ) == 0 ) then
call compute_si_operators( LS )
end if
```

- The LS (linearisation states) given as argument to `compute_si_operators` are obtained using the valid time of the `JEDI` increment object.
- The correct LS for the current time will always be passed to `compute_si_operators` (verified by the fact that our adjoint tests pass as long as `reference_reset_time == dt`).
- When `reference_reset_time == dt`, `reference_reset_freq == 1`, so the conditional will always evaluate to true and `compute_si_operators` will always be called, hence why our current configurations have a correct adjoint.
- As an example of a currently incorrect case, consider a 6-hour linear forecast followed by a 6-hour adjoint forecast (such as in an adjoint test or a single 4D-Var inner loop iteration) over a 0Z cycle.
- Say `dt == 3600` and `reference_reset_time == 7200`; this means `reference_reset_freq == 2`, so `compute_si_operators` will be called when the model clock step is 1, 3 and 5 but not when it's 2, 4 and 6.
- The linear and adjoint models both currrently use a forward ticking clock (see https://code.metoffice.gov.uk/trac/lfric_apps/ticket/267), so the correspondence of ''step numbers'' to ''step times and therefore LS'' in the linear forecast is
- 1, 21Z *
- 2, 22Z
- 3, 23Z *
- 4, 00Z
- 5, 01Z *
- 6, 02Z
- but in the adjoint forecast is
- 1, 02Z *
- 2, 01Z
- 3, 00Z *
- 4, 23Z
- 5, 22Z *
- 6, 21Z
- I have marked with asterixes the steps at which `compute_si_operators` is called; this means that the correspondence of ''step times'' to ''valid times of LS with which SI operators currently being used have been computed'' in the linear forecast is
- 21Z, 21Z
- 22Z, 21Z
- 23Z, 23Z
- 00Z, 23Z
- 01Z, 01Z
- 02Z, 01Z
- but in the adjoint forecast is
- 02Z, 02Z
- 01Z, 02Z
- 00Z, 00Z
- 23Z, 00Z
- 22Z, 22Z
- 21Z, 22Z
- whereas it should be
- 02Z, 01Z
- 01Z, 01Z
- 00Z, 23Z
- 23Z, 23Z
- 22Z, 21Z
- 21Z, 21Z
- This means that, in the adjoint, `compute_si_operators` needs to be called with LS that aren't the LS associated with the current time.
- Naturally this will be fairly tricky to get around since the place in the code at which the LS are updated based on the time (`jedi_lfric_tests`/`JEDI`) is some layers away from the timestepping code where `compute_si_operators` is called. The change will also need to be made in tandem with https://code.metoffice.gov.uk/trac/lfric_apps/ticket/267.

### Relevant log output

```shell

```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at tl_semi_implicit_alg_step and its adjoint, then trace how compute_si_operators receives linearisation states from jedi_lfric_tests and JEDI. Review the interaction with ticket 267 and run the relevant adjoint tests with reference_reset_time different from dt. Done means these tests pass while supporting reference_reset_time as a multiple of dt.

Written by the indexing model from the issue text.

Assessment

Tech stack
fortran
Domain
hpc
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.