Changes between Version 2 and Version 3 of ImplementAnalysisENSRF_EAKF


Ignore:
Timestamp:
Mar 24, 2025, 9:24:09 AM (4 weeks ago)
Author:
lnerger
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ImplementAnalysisENSRF_EAKF

    v2 v3  
    3939|| This page describes the implementation of the analysis step without using PDAF-OMI. Please see the [wiki:ImplementationofAnalysisStep page on the analysis with OMI] for the more modern and efficient implementation variant using PDAF-OMI. ||
    4040
    41 The LEnKF was added with verson 3.0 of PDAF.
     41The ENSRF/EAKF were added with verson 3.0 of PDAF.
    4242
    4343== Overview ==
     
    5353== `PDAF_assimilate_ensrf` ==
    5454
    55 The general aspects of the filter specific routines `PDAF_assimilate_*` have been described on the page [ModifyModelforEnsembleIntegration Modification of the model code for the ensemble integration] and its sub-page on [InsertAnalysisStep inserting the analysis step]. The routine is used in the fully-parallel and the flexible implementation variant of the data assimilation system. When the offline model is used the routines `PDAF_put_state_*' are used. These have also been used in previous PDAF releases for the 'flexible' implementation variant. Here, we list once more the full interface of the routine. Subsequently, the full set of user-supplied routines specified in the call to `PDAF_assimilate_ensrf` is explained.
     55The general aspects of the filter specific routines `PDAF_assimilate_*` have been described on the page [ModifyModelforEnsembleIntegration Modification of the model code for the ensemble integration] and its sub-page on [InsertAnalysisStep inserting the analysis step]. The routine is used in the fully-parallel and the flexible implementation variant of the data assimilation system. When the offline model is used the routines `PDAF_put_state_*` are used. These have also been used in previous PDAF releases for the 'flexible' implementation variant. Here, we list once more the full interface of the routine. Subsequently, the full set of user-supplied routines specified in the call to `PDAF_assimilate_ensrf` is explained.
    5656
    5757The interface when using the LEnKF is the following:
    5858{{{
    59   SUBROUTINE PDAF_assimilate_lenkf(U_collect_state, U_distribute_state, U_init_dim_obs, &
    60                                  U_obs_op, U_init_obs, U_prepoststep, U_localize, &
    61                                  U_add_obs_err, U_init_obscovar, U_next_observation, status)
     59  SUBROUTINE PDAF_assimilate_ensrf(U_collect_state, U_distribute_state, &
     60       U_init_dim_obs_f, U_obs_op_f, U_init_obs_f, U_init_obsvars_f, &
     61       U_localize_covar_serial, &
     62       U_prepoststep, U_next_observation, outflag)
    6263}}}
    6364with the following arguments:
    64  * [#U_collect_statecollect_state_pdaf.F90 U_collect_state]: The name of the user-supplied routine that initializes a state vector from the array holding the ensemble of model states from the model fields. This is basically the inverse operation to `U_distribute_state` used in `PDAF_get_state` as well as here.
    65  * [#U_distribute_statedistribute_state_pdaf.F90 U_distribute_state]:  The name of a user supplied routine that initializes the model fields from the array holding the ensemble of model state vectors.
    66  * [#U_init_dim_obsinit_dim_obs_pdaf.F90 U_init_dim_obs]: The name of the user-supplied routine that provides the size of observation vector
    67  * [#U_obs_opobs_op_pdaf.F90 U_obs_op]: The name of the user-supplied routine that acts as the observation operator on some state vector
    68  * [#U_init_obsinit_obs_pdaf.F90 U_init_obs]: The name of the user-supplied routine that initializes the vector of observations
    69  * [#U_prepoststepprepoststep_ens_pdaf.F90 U_prepoststep]: The name of the pre/poststep routine as in `PDAF_get_state`
    70  * [#U_localizelocalize_covar_pdaf.F90 U_localize]: Apply covariance localization to the matrices HP and HPH^T^
    71  * [#U_add_obs_erradd_obs_err_pdaf.F90 U_add_obs_err]: The name of the user-supplied routine that adds the observation error covariance matrix to the ensemble covariance matrix projected onto the observation space.
    72  * [#U_init_obscovarinit_obscovar_pdaf.F90 U_init_obscovar]: The name of the user-supplied routine that initializes the observation error covariance matrix.
    73  * [#U_next_observationnext_observation_pdaf.F90 U_next_observation]: The name of a user supplied routine that initializes the variables `nsteps`, `timenow`, and `doexit`. The same routine is also used in `PDAF_get_state`.
    74  * `status`: The integer status flag. It is zero, if `PDAF_assimilate_lenkf` is exited without errors.
    75 
    76 == `PDAF_put_state_lenkf` ==
    77 
    78 When the 'flexible' implementation variant is chosen for the assimilation system, the routine `PDAF_put_state_lenkf` has to be used instead of `PDAF_assimilate_lenkf`. The general aspects of the filter specific routines `PDAF_put_state_*` have been described on the page [ModifyModelforEnsembleIntegration Modification of the model code for the ensemble integration]. The interface of the routine is identical with that of `PDAF_assimilate_lenkf` with the exception the specification of the user-supplied routines `U_distribute_state` and `U_next_observation` are missing.
    79 
    80 The interface when using the LEnKF is the following:
    81 {{{
    82   SUBROUTINE PDAF_put_state_lenkf(U_collect_state, U_init_dim_obs, U_obs_op, &
    83                                  U_init_obs, U_prepoststep, U_localize, &
    84                                  U_add_obs_err, U_init_obscovar, status)
     65 * [#U_collect_statecollect_state_pdaf.F90 U_collect_state]: [[BR]]The name of the user-supplied routine that initializes a state vector from the array holding the ensemble of model states from the model fields. This is the inverse operation to `U_distribute_state` used in `PDAF_get_state` as well as here.
     66 * [#U_distribute_statedistribute_state_pdaf.F90 U_distribute_state]:  [[BR]]The name of a user supplied routine that initializes the model fields from the array holding the ensemble of model state vectors. This is the inverse operation to `U_collect_state`
     67 * [#U_init_dim_obs_finit_dim_obs_f_pdaf.F90 U_init_dim_obs_f]: [[BR]]The name of the user-supplied routine that provides the size of the full observation vector
     68 * [#U_obs_op_fobs_op_f_pdaf.F90 U_obs_op_f]: [[BR]]The name of the user-supplied routine that acts as the full observation operator on some state vector
     69 * [#U_init_obs_finit_obs_f_pdaf.F90 U_init_obs_f]: [[BR]]The name of the user-supplied routine that initializes the full vector of observations
     70 * [#U_init_obsvars_finit_obsvars_pdaf.F90 U_init_obsvars_f]: [[BR]]The name of the user-supplied routine that initializes the vector of observation error variances.
     71 * [#U_localize_covar_seriallocalize_covar_serial_pdaf.F90 U_localize_covar_serial]: [[BR]]The name of the routine that applies the covariance localization for a single observation
     72 * [#U_prepoststepprepoststep_ens_pdaf.F90 U_prepoststep]: [[BR]]The name of the pre/poststep routine as in `PDAF_get_state`
     73 * [#U_next_observationnext_observation_pdaf.F90 U_next_observation]: [[BR]]The name of a user supplied routine that initializes the variables `nsteps`, `timenow`, and `doexit`. The same routine is also used in `PDAF_get_state`.
     74 * `status_pdaf`: [[BR]]The integer status flag. It is zero, if the routine is exited without errors.
     75
     76== `PDAF_put_state_ensrf` ==
     77
     78For the offline mode of PDAF, the routine `PDAF_put_state_lenkf` has to be used instead of `PDAF_assimilate_lenkf`. This routine can also be used when the 'flexible' implementation variant is chosen for the assimilation system,  The general aspects of the filter specific routines `PDAF_put_state_*` have been described on the page [ModifyModelforEnsembleIntegration Modification of the model code for the ensemble integration]. The interface of the routine is identical with that of `PDAF_assimilate_lenkf` with the exception that the arguments of the user-supplied routines `U_distribute_state` and `U_next_observation` are missing.
     79
     80The interface is the following:
     81{{{
     82SUBROUTINE PDAF_put_state_ensrf(U_collect_state, &
     83     U_init_dim_obs_f, U_obs_op_f,  U_init_obs_f, U_init_obsvars_f, &
     84     U_localize_covar_serial, &
     85     U_prepoststep, outflag)
    8586}}}
    8687
     
    8889== User-supplied routines ==
    8990
    90 Here all user-supplied routines are described that are required in the call to `PDAF_assimilate_lenkf`. For some of the generic routines, we link to the page on [ModifyModelforEnsembleIntegration modifying the model code for the ensemble integration].
     91Here all user-supplied routines are described that are required in the call to `PDAF_assimilate_ensrf`. For some of the generic routines, we link to the page on [ModifyModelforEnsembleIntegration modifying the model code for the ensemble integration].
    9192
    9293To indicate user-supplied routines we use the prefix `U_`. In the tutorials in `tutorial/` and in the template directory `templates/` these routines exist without the prefix, but with the extension `_pdaf`. The files are named correspondingly. In the section titles below we provide the name of the template file in parentheses.
     
    106107See the page on [InsertAnalysisStep#U_distribute_statedistribute_state_pdaf.F90 inserting the analysis step] for the description of this routine.
    107108
    108 
    109 === `U_init_dim_obs` (init_dim_obs_pdaf.F90) ===
    110 
    111 This routine is used by all global filter algorithms (SEEK, SEIK, EnKF, ETKF) and by the LEnKF.
    112 
    113 The interface for this routine is:
    114 {{{
    115 SUBROUTINE init_dim_obs(step, dim_obs_p)
     109=== `U_init_dim_obs_f` (init_dim_obs_f_pdaf.F90) ===
     110
     111This routine is used by the ENSRF and by all filter algorithms with domain-localization (LSEIK, LETKF, LNETF, LKNETF) and is independent of the particular algorithm.
     112
     113The interface for this routine is:
     114{{{
     115SUBROUTINE init_dim_obs_f(step, dim_obs_f)
    116116
    117117  INTEGER, INTENT(in)  :: step       ! Current time step
    118   INTEGER, INTENT(out) :: dim_obs_p  ! Dimension of observation vector
    119 }}}
    120 
    121 The routine is called at the beginning of each analysis step.  It has to initialize the size `dim_obs_p` of the observation vector according to the current time step. Without parallelization `dim_obs_p` will be the size for the full model domain. When a domain-decomposed model is used, `dim_obs_p` will be the size of the observation vector for the sub-domain of the calling process.
     118  INTEGER, INTENT(out) :: dim_obs_f  ! Dimension of full observation vector
     119}}}
     120
     121For the ENSRF the routine is called at the beginning of each analysis step, before the loop over all single observations is entered.  It has to initialize the size `dim_obs_f` of the full observation vector according to the current time step. For simplicity, `dim_obs_f` can be the size for the global model domain.
    122122
    123123Some hints:
    124  * It can be useful to not only determine the size of the observation vector at this point. One can also already gather information about the locations of the observations, which will be used later, e.g. to implement the observation operator. An array for the locations can be defined in a module like `mod_assimilation` of the example implementation.
    125 
    126 
    127 === `U_obs_op` (obs_op_pdaf.F90) ===
    128 
    129 This routine is used by all global filter algorithms (SEEK, SEIK, EnKF, ETKF) and the LEnKF.
    130 
    131 The interface for this routine is:
    132 {{{
    133 SUBROUTINE obs_op(step, dim_p, dim_obs_p, state_p, m_state_p)
    134 
    135   INTEGER, INTENT(in) :: step               ! Currrent time step
     124 * We recommend to not only determine the size of the observation vector at this point. The routine is a good place to also already gather information about the corresponding indices of the state vector needed later to implement the observation operator. In addition, one can already prepare an array that holds the full observation vector and an array storing the coordinates of the observations. The required arrays can be defined in a module like `mod_assimilation`. The information can be used later in `U_localize_covar_serial`.
     125 * The routine is similar to `init_dim_obs` used in the global filters. However, if the global filter is used with a domain-decomposed model, it only initializes the size of the observation vector for the local model sub-domain. This is different for the local filters, as the local analysis also requires observational data from neighboring model sub-domains. Nonetheless, one can base on an implemented routine `init_dim_obs` to implement `init_dim_obs_f`.
     126
     127
     128=== `U_obs_op_f` (obs_op_f_pdaf.F90) ===
     129
     130This routine is used by the ENSRF and by all filter algorithms with domain-localization (LSEIK, LETKF, LNETF, LKNETF) and is independent of the particular algorithm.
     131
     132The interface for this routine is:
     133{{{
     134SUBROUTINE obs_op_f(step, dim_p, dim_obs_f, state_p, m_state_f)
     135
     136  INTEGER, INTENT(in) :: step               ! Current time step
    136137  INTEGER, INTENT(in) :: dim_p              ! PE-local dimension of state
    137   INTEGER, INTENT(in) :: dim_obs_p          ! Dimension of observed state
     138  INTEGER, INTENT(in) :: dim_obs_f          ! Dimension of the full observed state
    138139  REAL, INTENT(in)    :: state_p(dim_p)     ! PE-local model state
    139   REAL, INTENT(out) :: m_state_p(dim_obs_p) ! PE-local observed state
    140 }}}
    141 
    142 The routine is called during the analysis step. It has to perform the operation of the observation operator acting on a state vector that is provided as `state_p`. The observed state has to be returned in `m_state_p`.
    143 
    144 For a model using domain decomposition, the operation is on the PE-local sub-domain of the model and has to provide the observed sub-state for the PE-local domain.
    145 
    146 Hint:
    147  * If the observation operator involves a global operation, e.g. some global integration, while using domain-decomposition one has to gather the information from the other model domains using MPI communication.
    148 
    149 
    150 === `U_init_obs` (init_obs_pdaf.F90) ===
    151 
    152 This routine is used by all global filter algorithms (SEEK, SEIK, EnKF, ETKF) and the LEnKF.
    153 
    154 The interface for this routine is:
    155 {{{
    156 SUBROUTINE init_obs(step, dim_obs_p, observation_p)
    157 
    158   INTEGER, INTENT(in) :: step             ! Current time step
    159   INTEGER, INTENT(in) :: dim_obs_p        ! PE-local dimension of obs. vector
    160   REAL, INTENT(out)   :: observation_p(dim_obs_p) ! PE-local observation vector
    161 }}}
    162 
    163 The routine is called during the analysis step.
    164 It has to provide the vector of observations in `observation_p` for the current time step.
    165 
    166 For a model using domain decomposition, the vector of observations that exist on the model sub-domain for the calling process has to be initialized.
     140  REAL, INTENT(out) :: m_state_f(dim_obs_f) ! Full observed state
     141}}}
     142
     143The routine is called during the analysis step, before the loop over the single observations is entered. It has to perform the operation of the observation operator acting on a state vector, which is provided as `state_p`. The observed state has to be returned in `m_state_f`. It is the observed state corresponding to the 'full' observation vector.
     144
     145Hint:
     146 * The routine is similar to `init_dim_obs` used for the global filters. However, with a domain-decomposed model `m_state_f` will need to contain parts of the state vector from neighboring model sub-domains. Thus, one needs to collect this information which resides in the memory of other processes. PDAF provides the routine [wiki:PDAF_gather_obs_f PDAF_gather_obs_f] for this task. The example implementation in `tutorial/classical/online_2D_parallelmodel` shows the use of `PDAF_gather_obs_f`.
     147
     148
     149=== `U_init_obs_f` (init_obs_f_pdaf.F90) ===
     150
     151This routine is used by the ENSRF and by all filter algorithms with domain-localization (LSEIK, LETKF, LNETF, LKNETF) and is independent of the particular algorithm.
     152
     153The interface for this routine is:
     154{{{
     155SUBROUTINE init_obs_f(step, dim_obs_f, observation_f)
     156
     157  INTEGER, INTENT(in) :: step                     ! Current time step
     158  INTEGER, INTENT(in) :: dim_obs_f                ! Dimension of full observation vector
     159  REAL, INTENT(out)   :: observation_f(dim_obs_f) ! Full observation vector
     160}}}
     161
     162The routine is called during the analysis step before the loop over the single observations is entered. It has to provide the full vector of observations in `observation_f` for the current time step.
     163
     164Hints:
     165 * As for the other 'full' routines: While the global counterpart of this routine (`init_obs`) has to initialize the observation vector only for the local model sub-domain, the 'full' routine has to include observations that spatially belong to neighboring model sub-domains. As an easy choice one can simply initialize a vector of all globally available observations.
     166
     167
     168=== `U_init_obsvars_f` (init_obsvars_f_pdaf.F90) ===
     169
     170This routine is only used by the ENSRF/EAKF.
     171
     172The interface for this routine is:
     173{{{
     174SUBROUTINE init_obsvars_f(step, dim_obs_f, var_f)
     175
     176  INTEGER, INTENT(in) :: step           ! Current time step
     177  INTEGER, INTENT(in) :: dim_obs_f      ! Dimension of full observation vector
     178  REAL, INTENT(out) :: var_f(dim_obs_f) ! vector of observation error variances
     179}}}
     180
     181The routine is called during the analysis step before the loop over the single observations is entered. It has to provide in `var_f` a vector of observation error variances corresponding to the full vector of observations.
     182
     183=== `U_localize_covar_serial` (localize_covar_serial_pdaf.F90) ===
     184
     185This routine is only used by the ENSRF/EAKF.
     186
     187The interface for this routine is:
     188{{{
     189  SUBROUTINE U_localize_covar_serial(iobs, dim_p, dim_obs, HP_p, HXY_p)
     190
     191  INTEGER, INTENT(in) :: iobs                  !< Index of the assimilated single observation
     192  INTEGER, INTENT(in) :: dim_p                 !< Process-local state dimension
     193  INTEGER, INTENT(in) :: dim_obs_f             !< Number of full observations
     194  REAL, INTENT(inout) :: HP_p(dim_p)           !< Process-local part of matrix HP for observation iobs
     195  REAL, INTENT(inout) :: HXY_p(dim_obs_F)      !< Process-local part of matrix HX(HX_full) for full observations}}}
     196}}}
     197
     198The routine is called during the loop over all single observations. The purpose of the routine is to apply covariance localization to the vectors '''Hi P''' and '''Hi PH^T^''' for the assimilation of a single observation (determined by the index `iobs` related to the observation operator '''Hi'''). Here '''Hi PH^T^''' is the vector relating to the observed covariance matrix for the full observation vector. This vector is required for parallelization.
     199
     200Hints:
     201 * To compute the localization one can use the routine `PDAF_local_weight` after computing the distance between two elements in the vector '''Hi P''' or '''Hi PH^T'''.
    167202
    168203
     
    204239
    205240
    206 
    207 === `U_localize` (localize_covar_pdaf.F90) ===
    208 
    209 This routine is only used for the LEnKF.
    210 
    211 The interface for this routine is:
    212 {{{
    213 SUBROUTINE U_localize(dim_p, dim_obs, HP, HPH)
    214 
    215   INTEGER, INTENT(in) :: dim_p                 ! PE-local state dimension
    216   INTEGER, INTENT(in) :: dim_obs               ! Dimension of global observation vector
    217   REAL, INTENT(inout) :: HP(dim_obs, dim_p)    ! Matrix HP
    218   REAL, INTENT(inout) :: HPH(dim_obs, dim_obs) ! Matrix HPH^T^
    219 }}}
    220 
    221 The routine is called during the analysis step and has to apply the element-wise Schur product for the covariance localization of the two matrices'''HP''' and '''HPH^T^''', which are provided as input/output arguments.
    222 
    223 Notes:
    224  * In case of a parallelization with domain decomposition, `HP` contains only the columns of the matrix that resides on the model sub-domain of the calling process. The number of rows is that of the global number of observations
    225 
    226 Hints:
    227  * To compute the localization one can use the routine `PDAF_local_weight` after computing the distance between two elements in the matrix '''HP''' or '''HPH^T^'''.
    228 
    229 
    230 === `U_add_obs_err` (add_obs_err_pdaf.F90) ===
    231 
    232 This routine is only used for the EnKF and LEnKF.
    233 
    234 The interface for this routine is:
    235 {{{
    236 SUBROUTINE add_obs_err(step, dim_obs, C)
    237 
    238   INTEGER, INTENT(in) :: step                ! Current time step
    239   INTEGER, INTENT(in) :: dim_obs             ! Dimension of obs. vector
    240   REAL, INTENT(inout) :: C(dim_obs, dim_obs) ! Matrix to that the observation
    241                                              !    error covariance matrix is added
    242 }}}
    243 
    244 The routine is called during the analysis step. During the analysis step of the LEnKF, the projection of the ensemble covariance onto the observation space is computed. This matrix is provided to the routine as `C_p`. The routine has to add the observation error covariance matrix to `C_p`.
    245 
    246 The operation is for the global observation space. Thus, it is independent of whether the filter is executed with or without parallelization.
    247 
    248 Hints:
    249  * The routine does not require that the observation error covariance matrix is added as a full matrix. If the matrix is diagonal, only the diagonal elements have to be added.
    250 
    251 
    252 
    253 === `U_init_obscovar` (init_obscovar_pdaf.F90) ===
    254 
    255 This routine is only used for the EnKF and LEnKF.
    256 
    257 The interface for this routine is:
    258 {{{
    259 SUBROUTINE init_obscovar(step, dim_obs, dim_obs_p, covar, m_state_p, &
    260      isdiag)
    261 
    262   INTEGER, INTENT(in) :: step                ! Current time step
    263   INTEGER, INTENT(in) :: dim_obs             ! Dimension of observation vector
    264   INTEGER, INTENT(in) :: dim_obs_p           ! PE-local dimension of observation vector
    265   REAL, INTENT(out) :: covar(dim_obs, dim_obs) ! Observation error covariance matrix
    266   REAL, INTENT(in)  :: m_state_p(dim_obs_p)  ! PE-local observation vector
    267   LOGICAL, INTENT(out) :: isdiag             ! Whether the observation error covar. matrix is diagonal
    268 }}}
    269 
    270 The routine is called during the analysis step and is required for the generation of an ensemble of observations. It has to initialize the global observation error covariance matrix `covar`. In addition, the flag `isdiag` has to be initialized to provide the information, whether the observation error covariance matrix is diagonal.
    271 
    272 The operation is for the global observation space. Thus, it is independent of whether the filter is executed with or without parallelization.
    273 
    274 Hints:
    275  * The local observation vector `m_state_p` is provided to the routine for the case that the observation errors are relative to the value of the observation.
    276 
    277 
    278241=== `U_next_observation` (next_observation_pdaf.F90) ===
    279242
     
    285248== Execution order of user-supplied routines ==
    286249
    287 For the :EnKF, the user-supplied routines are essentially executed in the order they are listed in the interface to `PDAF_assimilate_lenkf`. The order can be important as some routines can perform preparatory work for later routines. For example, `U_init_dim_obs` can prepare an index array that provides the information for executing the observation operator in `U_obs_op`.
     250For the ENSRF/EAKF methods, the user-supplied routines are essentially executed in the order they are listed in the interface to `PDAF_assimilate_ensrf`. The order can be important as some routines can perform preparatory work for later routines. For example, `U_init_dim_obs` can prepare an index array that provides the information for executing the observation operator in `U_obs_op`.
    288251
    289252Before the analysis step is called the following routine is executed:
     
    293256 1. [#U_prepoststepprepoststep_ens_pdaf.F90 U_prepoststep] (Call to act on the forecast ensemble, called with negative value of the time step)
    294257 1. [#U_init_dim_obsinit_dim_obs_pdaf.F90 U_init_dim_obs]
    295  1. [#U_obs_opobs_op_pdaf.F90 U_obs_op] (`dim_ens` calls: one call for each ensemble member)
    296  1. [#U_localizelocalize_covar_pdaf.F90 U_localize]
    297  1. [#U_add_obs_erradd_obs_err_pdaf.F90 U_add_obs_err]
     258 1. [#U_obs_opobs_op_pdaf.F90 U_obs_op] (`dim_ens` calls: one call for each ensemble member; one more call if also applied to ensemble mean)
    298259 1. [#U_init_obsinit_obs_pdaf.F90 U_init_obs]
    299  1. [#U_init_obscovarinit_obscovar_pdaf.F90 U_init_obscovar]
    300  1. [#U_obs_opobs_op_pdaf.F90 U_obs_op] (`dim_ens` calls: one call for each ensemble member, repeated to reduce storage)
     260 1. [#U_init_varsinit_obsvars_pdaf.F90 U_init_obsvars]
     261
     262In the loop over all single observations, only one call-back routine is executed:
     263 1. [#U_localize_covar_seriallocalize_covar_serial_pdaf.F90 U_localize_covar_serial] (once for each single observation)
     264
     265After the loop over all local analysis domains, it is executed:
    301266 1. [#U_prepoststepprepoststep_ens_pdaf.F90 U_prepoststep] (Call to act on the analysis ensemble, called with (positive) value of the time step)
    302267
    303 In case of the routine `PDAF_assimilate_enkf`, the following routines are executed after the analysis step:
     268In case of the routine `PDAF_assimilate_ensrf`, the following routines are executed after the analysis step:
    304269 1. [#U_distribute_statedistribute_state_pdaf.F90 U_distribute_state]
    305270 1. [#U_next_observationnext_observation_pdaf.F90 U_next_observation]