53 | | SUBROUTINE PDAF_put_state_generate_obs(U_collect_state, U_init_dim_obs_f, U_obs_op_f, U_get_obs_f, & |
54 | | U_init_obserr_f, U_prepoststep, status_pdaf) |
| 53 | SUBROUTINE PDAF_put_state_generate_obs(U_collect_state, U_init_dim_obs_f, U_obs_op_f, U_init_obserr_f, & |
| 54 | U_get_obs_f, U_prepoststep, status_pdaf) |
| 86 | === `U_init_obserr_f` (init_obserr_f_pdaf.F90) === |
| 87 | |
| 88 | This routine is specific for the observation generation. The routine is called by PDAF during the observation generation. Its purpose is to fill the provided vector of observation error standard deviations. |
| 89 | |
| 90 | The interface is the following: |
| 91 | {{{ |
| 92 | SUBROUTINE init_obserr_f_pdaf(step, dim_obs_f, obs_f, rms_obs) |
| 93 | }}} |
| 94 | with |
| 95 | * `step` : `integer, intent(in)`[[BR]] Current time step |
| 96 | * `dim_obs_f` : `integer, intent(in)`[[BR]] Size of full observation vector |
| 97 | * `obs_f` : `real, intent(in), dimension(dim_obs_f)`[[BR]] Full vector of observations |
| 98 | * `rms_obs` : `real, intent(out), dimension(dim_obs_f)`[[BR]] Full vector of observation error standard deviations |
| 99 | |
| 100 | Notes: |
| 101 | * The routines handles the 'full' observation vector as in localizated filters. As described for the observation generation functionality one can also use it for global filters. In this case the 'full' vector would just contain the observations local to a process sub-domain. |
| 102 | * The observation vector `obs_f` is provided to the routine for the case that the observation error is relative to the value of the observations. |
| 103 | |
105 | | === `U_init_obserr_f` (init_obserr_f_pdaf.F90) === |
106 | | |
107 | | This routine is specific for the observation generation. The routine is called by PDAF during the observation generation. Its purpose is to fill the provided vector of observation error standard deviations. |
108 | | |
109 | | The interface is the following: |
110 | | {{{ |
111 | | SUBROUTINE init_obserr_f_pdaf(step, dim_obs_f, obs_f, rms_obs) |
112 | | }}} |
113 | | with |
114 | | * `step` : `integer, intent(in)`[[BR]] Current time step |
115 | | * `dim_obs_f` : `integer, intent(in)`[[BR]] Size of full observation vector |
116 | | * `obs_f` : `real, intent(in), dimension(dim_obs_f)`[[BR]] Full vector of observations |
117 | | * `rms_obs` : `real, intent(out), dimension(dim_obs_f)`[[BR]] Full vector of observation error standard deviations |
118 | | |
119 | | Notes: |
120 | | * The routines handles the 'full' observation vector as in localizated filters. As described for the observation generation functionality one can also use it for global filters. In this case the 'full' vector would just contain the observations local to a process sub-domain. |
121 | | * The observation vector `obs_f` is provided to the routine for the case that the observation error is relative to the value of the observations. |
122 | | |
123 | | |
| 135 | The observation-generation with `PDAF_generate_obs` or `PDAF_put_state_generate_obs` works analogously to the observation handling in the localized filters like LESTKF and LETKF. However, the observation generation does not modify the ensemble states and `prepoststep_pdaf` is only called once before the each observation generation, but not afterwards. The routine `init_dim_obs_f_pdaf` can be identical to the actuall assimilation case. It initializes the full observation dimension and usually also some more observation information (as described e.g. on the [wikio:init_dim_obs_f_pdaf detail page on init_dim_obs_f_pdaf]. Subsequently `obs_op_f_pdaf` is applied. One can run the ensemble generation with a single ensemble member (dim_ens=1) or a larger ensemble. If dim_ens>1, the observation operator is applied to the ensemble mean state. The routine `init_obserr_f_pdaf` provides PDAF with the vector of observation error standard deviations. This is used in combination with Gaussian random noise to compute the perturbations that are added to the true state to generate the observations. Finally `get_obs_f_pdaf` gives the user access to the generated synthetic observation vector so that one can write it to a file for later use (See the [wiki:readwrite_obs page on the template file readwrite_obs.F90] for a description how the observations can be written to a file and used later on). |
| 136 | |
| 137 | If one has access to real observations, one can use the implementation of `init_dim_obs_f_pdaf` and `obs_ob_f_pdaf` for these observations to generate synthetic observations simulating these real observations. Thus one runs the observation generation using these routines without any modifications. |
| 138 | |
| 139 | |
| 140 | == Using the synthetic observations in twin experiments == |
| 141 | |
| 142 | To perform a twin experiment using the synthetic observations generated by PDAF, one runs the data assimilation as one would with real observations. If one already initializes the vector of actual observations in the routine `init_dim_obs_f` one only needs to small modification of this routine. Namely, only required modification is that at the end of `init_dim_obs_f` one overwrites the vector of real observations with the values from the synthetic observations. If one uses the template file `readwrite_obs.F90` for this, one can use `read_syn_obs` from this file at the end of `init_dim_obs_f` to overwrite the observatio vector. To allow for a flexible switching between the case using real observations and the twin experiment, one can for example introduce a flag `twin_experiment` that controls whether the real observation values are overwritten. |
| 143 | |
| 144 | Example implementations using `PDAF_put_state_generate_obs` and `readwrite_obs.F90` are provided by the two test cases `testsuite/src/dummymodel_1D` and `testsuite/src/lorenz96`. These also use the flag `twin_experiment` to actiavate the twin experiment (Note: These two test cases always use simulated observations. Nonetheless, they allow to see how the synthetic observations are generated with PDAF and how they are used in a twin experiment). |
| 145 | |