Skip to content

Inflation Testing

Tim Hoar edited this page Mar 5, 2021 · 12 revisions

Overview:

You need a case where we expect the inflation to do something. Since all the models use the same inflation code, it doesn't matter which model. The test should be fast. Since some of these algorithms adapt, the test should have multiple assimilation cycles. All locations are treated similarly, so any location will do. If the localization is large enough to impact more than one location - this is a sufficient test to ensure that spatially-varying inflations vary spatially and spatially-constant inflations are spatially constant.

Fortran

The following scripts/files can be used to exhaustively test all the inflation algorithms that we support - as both prior and posterior inflation. At present, all tests are repeated on the Manhattan branch and the feature branch - but this requires two separate clones, and the mkmf.template file should be identical on both clones (each clone has one of the branches). The test_inflation.csh and CheckInflation.m will require customization to reflect the location of your DART branches.

I chose to use the Lorenz 96 model for the test. I created a single identity observation (-10) and repeated it for 3 cycles - since time_step_seconds is 3600 seconds (i.e. times 0,0 ... 3600,0 ... 7200,0) ran it through perfect_model_obs, and then manually biased the observation to force the separation of the observation value and the ensemble. I also changed the model forcing (pmo was run with 8.0, filter with 9.0) for the same reason. I left the cutoff at 0.02 which results in impacting 3 spatial locations (#9,#10,#11). I used the model states that result from running workshop_setup.csh or quickbuild.csh.

To recap the input.nml I was using for the inflation testing:

   inf_initial        =       1.1,       1.2
   inf_sd_initial     =       0.6,       0.6
   inf_initial        =       1.1,       1.2
   inf_lower_bound    =       0.1,       0.1
   inf_upper_bound    = 1000000.0, 1000000.0
   inf_damping        =       0.9,       0.9
   inf_sd_initial     =       0.6,       0.6
   inf_sd_lower_bound =       0.5,       0.5
   inf_sd_max_change  =      1.05,       1.05
   ...
   cutoff  = 0.02
   ...
   forcing = 9.00

Put another way:

diff inf_3_4/input.nml ../work/input.nml
55c55
<    obs_sequence_in_name = 'obs_seq.out.inf_test'
---
>    obs_sequence_in_name         = "obs_seq.out",
65c65
<    inf_flavor = 3, 4
---
>    inf_flavor                  = 2,                       0,
69,75c69,75
<    inf_initial = 1.1, 1.2
<    inf_lower_bound = 0.0, 0.0
<    inf_upper_bound = 1000000.0, 1000000.0
<    inf_damping = 0.9, 0.9
<    inf_sd_initial = 0.6, 0.6
<    inf_sd_lower_bound = 0.5, 0.5
<    inf_sd_max_change = 1.05, 1.05
---
>    inf_initial                 = 1.0,                     1.0,
>    inf_lower_bound             = 1.0,                     1.0,
>    inf_upper_bound             = 1000000.0,               1000000.0,
>    inf_damping                 = 0.9,                     1.0,
>    inf_sd_initial              = 0.6,                     0.0,
>    inf_sd_lower_bound          = 0.6,                     0.0,
>    inf_sd_max_change           = 1.05,                    1.05,
97c97
<    cutoff = 0.02
---
>    cutoff                          = 0.02,
133c133
<    forcing = 9.0
---
>    forcing           = 8.00,

actually testing

test_inflation.csh needs to be modified to refer to the two directories to compare. Stage the obs_seq.out.inf_test file in one or both of the lorenz_96/work directories. Make sure both directories have the same compile options. If both lorenz_96/work/filters are compiled, test_inflation.csh takes about a minute on my Mac laptop. It creates 42 directories with names like lorenz_96/work/inf_2_4 with the contents for the each experiment - In each of the comparison directories (84 directories total).

CheckInflation.m compares the netCDF files that have the states as well as the inflation values. It relies on the DART matlab function Compare_netCDF_files so the DART diagnostics/matlab directory must be part of your matlabpath.

using the character string representation:

There is a duality between the inflation flavor specified as an integer and that specified by a string.

character string integer
'NO_INFLATION' 0
'OBS_INFLATION' 1
'VARYING_SS_INFLATION' 2
'SINGLE_SS_INFLATION' 3
'RELAXATION_TO_PRIOR_SPREAD' 4
'RTPS' 4
'ENHANCED_SS_INFLATION' 5

These two namelist options are equivalent:

inf_flavor     = 0,                     4
inf_flavor     = 'NO_INFLATION',    'RTPS'

DART_LAB Matlab vs. Fortran

This section is devoted to comparing the results of the DART_LAB Matlab private/update_inflate.m function with the Fortran adaptive_inflate_mod:update_inflation() routine. There is more to inflation than just these routines - there is localization and damping, etc. Those aspects of inflation are not being tested.

Overview

Coming soon ....

To test the reproducibility of the routines, it is necessary to provide identical input to the functions. The strategy taken is to capture the input to and results from the Fortran routine and write out a small file that can be read into Matlab. Since the algorithms in these routines are not aware of other spatial locations, it is sufficient to test it with the input for one location (all ensemble members and the observation and its variance, etc). These routines also do not test the 'damping' of the inflation algorithms, so only 1 timestep is needed.

The adaptive_inflate_mod.f90 has a logical flag to enable the creation of a matlab script that contains the input necessary to compare the algorithms in update_inflation() and update_inflate.m. Since adaptive_inflate_mod does not have a namlist, this flag must be hand-edited and compiled in. This file will only write out the file once - the first time the update_inflation() function is called.

Once filter has run, it creates a inflation_input.m file. Just leave it in the lorenz_63/work/ directory. Since the intent is to directly call the (private) matlab function update_inflate, it is sufficient to

cd ../../../docs/DART_LAB/matlab/private
matlab -nodesktop
>> inflation_test
fortran inflation value, sd is 1.072872 0.600000
matlab  inflation value, sd is 1.072872 0.600000
>> 

We are only testing inf_flavor 2 and 5, so the input.nml must be changed and repeated. The whole thing can be improved, but its a start.