Changes between Initial Version and Version 1 of AuxiliaryRoutines_PDAF23


Ignore:
Timestamp:
May 19, 2025, 8:09:03 AM (12 days ago)
Author:
lnerger
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AuxiliaryRoutines_PDAF23

    v1 v1  
     1= Auxiliary Routines in PDAF 2 =
     2
     3[[PageOutline(2-3,Contents of this page)]]
     4
     5PDAF provide a number of auxiliary routines. They provide access to PDAF-internal data, which is not available through the regular interface of PDAF.
     6
     7== Interface specifications ==
     8
     9=== PDAF_interfaces_module.F90 ===
     10
     11This file contains the module `PDAF_interfaces_module`. It provides interface definitions for the routines of PDAF. If you like to use explicit Fortran interfaces, or if you have to use then in case of the smoother, you have to include the following line in the header you the calling routine:
     12
     13{{{
     14  use PDAF_interfaces_module
     15}}}
     16
     17
     18
     19== Access to PDAF-internal arrays ==
     20
     21=== PDAF_get_smootherens ===
     22
     23A smoother is available for several filters (ESTKF/LESTKF/ETKF/LETKF/EnKF). This routine is called to set a Fortran pointer to the array in PDAF that stores the ensembles for smoothing. Also, the routine sets the available lag of the smoothing.
     24
     25{{{
     26CALL PDAF_get_smootherens(sens_pointer, maxlag, status)
     27}}}
     28
     29The variables in the interface are the following:
     30
     31 * `sens_pointer`: The pointer to the smoother ensemble. The dimension is `sens_pointer(:,:,:)`. Thus in the program calling `PDAF_get_smootherens` one has to declare `REAL, POINTER :: sens_pointer(:,:,:)`. On output it points to the smoother ensemble.
     32 * `maxlag`: Number of lags stored in the smoother ensemble. While in the call to `PDAF_init` the maximum lag for the smoother is set, not all possible lags are using at the beginning of the assimilations. `maxlag` shows how many times were already smoothed.
     33 * `status`: Status flag. 0 for successful exit.
     34
     35'''Important:'''
     36
     37 * Because `sens_pointer` is a pointer, the call to `PDAF_get_smootherens` needs an ''explicit'' Fortran interface. This is provided by the Fortran module `PDAF_interfaces_module`. In the header part of the routine that calls `PDAF_get_smootherens` one has to include `use PDAF_interfaces_module`!
     38 * Using a pointer combined with an intent, i.e. using a pointer as argument, is a feature of Fortran 2003. Thus, if a too old compiler is used, it will provide an error when the routine is compiled.
     39
     40Notes:
     41
     42 * `PDAF_get_smootherens` is typically called in the prepoststep routine after the analysis step. At this time not only the filtered analysis step can be analized, but also all smoothed ensembles.
     43 * The first two indices of `sens_pointer` are identical to those in the ensemble array `ens_p`. Thus, the array contains state vectors in its columns. The second index is the ensemble index. The third index is the lag. Thus, if the value of the third index is fixed one can use the array `sens_pointer` analogous to the ensemble array `ens_p`.
     44 * For an example using `PDAF_get_smootherens` see the implementation for the Lorenz96 model in `models/lorenz96/`. The routine is called in `compute_rms_smoother.F90`.
     45
     46 
     47
     48=== PDAF_set_smootherens ===
     49
     50A smoother is available for several filters (ESTKF/LESTKF/ETKF/LETKF/EnKF/NETF/LNETF). This routine is called to set a Fortran pointer to the array in PDAF that stores the ensembles for smoothing. In addition, it sets the available lag of the smoothing. This routine is called in the offline mode of PDAF. While in the online mode, the smoother ensemble array is filled automatically by PDAF, one has to fill it manually in the offline mode. `PDAF_set_smootherens` gives access to the smoother array to fill it.
     51
     52{{{
     53CALL PDAF_set_smootherens(sens_pointer, maxlag, status)
     54}}}
     55
     56The arguments are:
     57
     58 * `sens_pointer`: The pointer to the smoother ensemble. The dimension is `sens_pointer(:,:,:)`. Thus in the program calling `PDAF_get_smmotherens` one has to declare `REAL, POINTER :: sens_pointer(:,:,:)`. On output it points to the smoother ensemble.
     59 * `maxlag`: Set the number of lags stored in the smoother ensemble. While in the call to `PDAF_init` the maximum lag for the smoother is set, not all possible lags are using at the beginning of the assimilations. `maxlag` says how many times were already smoothed. Both values are usually identical for the offline mode.
     60 * `status`: Status flag. 0 for successful exit.
     61
     62
     63'''Important:'''
     64
     65 * Because `sens_pointer` is a pointer, the call to `PDAF_set_smootherens` needs an ''explicit'' Fortran interface. This is provided by the Fortran module `PDAF_interfaces_module`. In the header part of the routine that calls `PDAF_set_smootherens` one has to include `use PDAF_interfaces_module`!
     66 * Using a pointer combined with an intent, i.e. using a pointer as argument, is a feature of Fortran 2003. Thus, if a too old compiler is used, it will provide an error when the routine is compiled.
     67
     68
     69Notes:
     70
     71 * `PDAF_set_smootherens` is typically called in the initialization phase of PDAF. It was to be called after the basic initialization of PDAF in `PDAF_init`. A possible location is to call `PDAF_set_smootherens` is the ensemble initialization routine `U_init_ens`.
     72 * The first two indices of `sens_pointer` are identical to those in the ensemble array `ens_p`. Thus, the array contains state vectors in its columns. The second index is the ensemble index. The third index is the lag. Thus, if the value of the third index is fixed one can use the array `sens_pointer` analogous to the ensemble array `ens_p`.
     73
     74
     75=== PDAF_set_ens_pointer ===
     76
     77This routine allows a program to get a Fortran pointer to the internal ensemble array of PDAF.
     78
     79{{{
     80CALL PDAF_set_ens_pointer(ens_pointer, status)
     81}}}
     82
     83The arguments are:
     84
     85 * `ens_pointer`: The pointer to the smoother ensemble. The dimension is `ens_pointer(:,:)`. Thus in the program calling `PDAF_set_ens_pointer` one has to declare `REAL, POINTER :: sens_pointer(:,:)`. On output it points to the ensemble array.
     86 * `status`: Status flag. 0 for successful exit.
     87
     88
     89'''Important:'''
     90
     91 * Because `ens_pointer` is a pointer, the call to `PDAF_set_ens_pointer` needs an ''explicit'' Fortran interface. This is provided by the Fortran module `PDAF_interfaces_module`. In the header part of the routine that calls `PDAF_set_ens_pointer` one has to include `use PDAF_interfaces_module`!
     92 * Using a pointer combined with an intent, i.e. using a pointer as argument, is a feature of Fortran 2003. Thus, if a too old compiler is used, it will provide an error when the routine is compiled.
     93
     94
     95Notes:
     96
     97 * `PDAF_set_ens_pointer` is a special routine that is never needed when the standard online or offline modes of the implementation are used. However, the routine allows to build a model that uses each column of the ensemble array to store the model fields. Thus, one can avoid allocating additional memory for the model fields.
     98
     99
     100== Access to index information ==
     101
     102=== PDAF_get_memberid ===
     103
     104This routine can be called from the model during an ensemble integration. It provides access to the number (id) of the ensemble member that is currently integrated.
     105
     106{{{
     107CALL PDAF_get_memberid(memberid)
     108}}}
     109
     110The only argument is:
     111 * `memberid`: In integer providing on output the id the ensemble member
     112
     113Note:
     114 * Using `PDAF_get_memberid` is obviously only useful if more than one ensemble member is integrated by a model task. If there are as many model tasks as ensemble members, `memberid` is always 1. In this case one can use `task_id` from the module `mod_parallel` to distinguish the ensemble members.
     115
     116
     117=== PDAF_get_obsmemberid ===
     118
     119This routine can be called from the model during the analysis step. It provides access to the number (id) of the ensemble member for which the user-routine for the observation operator is called.
     120
     121{{{
     122CALL PDAF_get_obsmemberid(memberid)
     123}}}
     124
     125The only argument is:
     126 * `memberid`: In integer providing on output the id the ensemble member
     127
     128Note:
     129 * The routine an be useful if the observation operator does not actually operate on the state vector that is provided when [wiki:obs_op_pdaf] is called. Their might be cases in which one likes to read model state information from a file (e.g. if the observation operator performs an averaging over time, while the state vector for the analysis step only contains a single time instance).
     130
     131
     132== Incremental analysis updates ==
     133
     134=== PDAF_incremental ===
     135
     136When incremental updating is used, this routine is called during the forecast phase to add a fraction of the analysis increment to an ensemble member.
     137
     138{{{
     139CALL PDAF_incremental(steps, U_dist_stateinc)
     140}}}
     141
     142The arguments are:
     143 * `steps`: The number of time steps over which the increment should be distributed
     144 * `U_dist_stateinc`: The name of the user supplied call-back function that performs the actual addition of the state vector increment to the individual model fields.
     145
     146
     147=== PDAF_add_increment ===
     148
     149When incremental updating is used, the state increment of the analysis step is not directly added to the forecast state. To add the increment to some state vector `PDAF_add_increment` is called:
     150
     151{{{
     152CALL PDAF_add_increment(dim_p, state_p)
     153}}}
     154
     155The arguments are
     156 * `dim_p`: An integer giving the state dimension of `state_p`
     157 * `state_p`: A real array of size `dim_p` holding the on input the state vector and on output the state vector plus increment.
     158
     159Note:
     160 * the routine can be used in the prepoststep routine when the analysis state should be analyzed.
     161
     162
     163
     164== Controlling the MPI communicator for PDAF ==
     165
     166=== PDAF_set_comm_pdaf ===
     167
     168This routie allows to sepacify the communicator on which the overall PDAF communication bases.
     169
     170By default, PDAF bases on `MPI_COMM_WORLD`, thus all processes in a program. This routine allows to set a different communicator. This can be useful if a model is e.g. run with an OI-server so that the world communicator is split into processes for the IO (file) operations and other processes for the actual model run. In this casem, the model would run using a communicator distinct from `MPI_COMM_WORLD` and PDAF should operate only with this communicator. `PDAF_set_comm_pdaf` allows the user to specify this communicator for PDAF.
     171
     172{{{
     173SUBROUTINE PDAF_set_comm_pdaf(comm_pdaf)
     174
     175  INTEGER,INTENT(in) :: comm_pdaf    ! MPI communicator for PDAF
     176}}}
     177
     178Notes:
     179 * `comm_pdaf` has to be used consistently in `init_parallel_pdaf` where the commuicators for PDAF are prepared on the user side.
     180 * The size of `comm_pdaf` has to be large enough so that the ensemble run can be performed
     181 * `PDAF_set_comm_pdaf` has to be called before calling `PDAF_init`
     182
     183== Debugging ==
     184
     185=== PDAF_set_debug_flag ===
     186
     187This routine was introduced with PDAF V2.1.
     188
     189the routine allows to activate debugging output. See the [wiki:PDAF_debugging documention on PDAF debuggging] for more information.
     190
     191== Additional (advanced) functionality ==
     192
     193=== PDAF_reset_forget ===
     194
     195This routine was introduced with PDAF V2.0
     196
     197The routine allows a user to reset the forgetting factor manually during the assimilation process.
     198
     199For the local ensemble Kalman filters the forgetting factor can be set either globally of differently for each local analysis domain. For the LNETF and the global filters only a global setting of the forgeting factor is possible. This routine allows users to set the forgetting factor case-specific. In addition, the implementation of adaptive choices for the forgetting factor (beyond what is implemented in PDAF) are possible.
     200
     201The interface is the following:
     202{{{
     203  SUBROUTINE PDAF_reset_forget(forget)
     204}}}
     205with the following argument:
     206 * `forget`: `real, intent(in)`[[BR]] The new value of the forgetting factor
     207
     208'''How to use PDAF_reset_forget'''
     209
     210 * '''Global Filters and LNETF''': For global filters `PDAF_reset_forget` has to be called before the actual analysis step. Within the PDAF context the call can be inserted in `prepoststep_pdaf`. Alternatively, the call can be inserted in the routine `assimilation_pdaf` before the call to the PDAF_assimilate_X or PDAF_put_state_X routines
     211 * '''Local Filters''':
     212  * global setting: The forgetting factor is reset globally, thus equal for all local analysis dimains, if `PDAF_reset_forget` is called before the local analysis loop is executed (e.g. in `init_obs_pdomi` or earlier in the analysis step; see [ImplementAnalysisLocal] for the order of the execution of the call-back routines). Thus, it can also be called in `prepoststep_pdaf` to get a global seeting as fo rthe global filters.
     213  * To reset `forget` specific for each local analysis domain, `PDAF_reset_forget` should be called during the local analysis loop. In particular the routines `init_dim_l` or `init_dim_obs_l_pdafomi` are suited for this.
     214
     215
     216=== PDAF_force_analysis ===
     217
     218This routine was introduced with PDAF 2.0.
     219
     220The routine allows a user to enforce the execution of the analysis step at the next call to `PDAF_put_state_X` or `PDAF_assimilate_X`.
     221
     222In particular for `PDAF_assimilate_X`, the number of time steps is set before the forecast phase is entered. However, one might not know the actual length of the forecast time, e.g. the time when new observation arrive. In this case, one can set for number of time steps to a large value and then check for new observations during the time stepping and call `PDAF_force_analysis` just before `PDAF_assimilate_X` is called to enforce that the analysis step is executed.
     223
     224[[span(style=color: #FF0000, '''Warning:''' This is a routine for advanced functionality of PDAF. Use it carefully, since it can break the assimilation process.)]]
     225
     226For `PDAF_put_state_X`, one can use `PDAF_force_analysis` to overwrite the counting of the ensemble members that PDAF does internally.
     227
     228{{{
     229  SUBROUTINE PDAF_reset_forget()
     230}}}
     231without any argument
     232
     233
     234=== PDAF_set_memberid ===
     235
     236This routine was introduced with PDAF 2.0.
     237
     238The routine allows a user to reset the ensemble member counter inside PDAF. This routine should only be used in the flexible parallelization mode, thus when `PDAF_put_state_X` is used. Resetting the member counter, allows e.g. to enforce the execution of the analysis step in the case, when according to the PDAF-internal counter, the ensemble integration is not yet complete. For this, one has to specify the member-ID to be the ensemble size.
     239
     240To just enforce an analysis step, we recommend to use the routine [wiki:PDAF_force_analysis]. This routine is also compatible with `PDAF_assimilate_X`.
     241
     242[[span(style=color: #FF0000, '''Warning:''' This is a routine for advanced functionality of PDAF. Use it carefully, since it can break the assimilation process.)]]
     243
     244The interface is the following:
     245{{{
     246  SUBROUTINE PDAF_set_memberid(member)
     247}}}
     248without the argument:
     249 * `member`: `integer, intent(in)` Member in index to which the PDAF-internal counting is reset.