New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
diamlr.F90 in NEMO/branches/2019/dev_r11879_ENHANCE-05_SimonM-Harmonic_Analysis/src/OCE/DIA – NEMO

source: NEMO/branches/2019/dev_r11879_ENHANCE-05_SimonM-Harmonic_Analysis/src/OCE/DIA/diamlr.F90 @ 11950

Last change on this file since 11950 was 11950, checked in by smueller, 4 years ago

Addition of a placeholder substitution mechanism for the inclusion of tidal-constituent parameters, which are available from the tidal-forcing implementation, in regressor expressions for multiple-linear-regression analysis (see ticket #2175)

File size: 16.5 KB
Line 
1MODULE diamlr
2   !!======================================================================
3   !!                       ***  MODULE  diamlr  ***
4   !! Management of the IOM context for multiple-linear-regression analysis
5   !!======================================================================
6   !! History :       !  2019  (S. Mueller)
7   !!----------------------------------------------------------------------
8
9   USE par_oce        , ONLY :   wp, jpi, jpj
10   USE phycst         , ONLY :   rpi
11   USE in_out_manager , ONLY :   lwp, numout, ln_timing
12   USE iom            , ONLY :   iom_put, iom_use, iom_update_file_name
13   USE dom_oce        , ONLY :   adatrj
14   USE timing         , ONLY :   timing_start, timing_stop
15   USE xios
16   USE tide_mod       , ONLY :   tide_harmo, jpmax_harmo, Wave
17
18   IMPLICIT NONE
19   PRIVATE
20
21   LOGICAL, PUBLIC ::   lk_diamlr = .FALSE.
22
23   PUBLIC ::   dia_mlr_init, dia_mlr_iom_init, dia_mlr
24
25   !!----------------------------------------------------------------------
26   !! NEMO/OCE 4.0 , NEMO Consortium (2019)
27   !! $Id$
28   !! Software governed by the CeCILL license (see ./LICENSE)
29   !!----------------------------------------------------------------------
30CONTAINS
31   
32   SUBROUTINE dia_mlr_init
33      !!----------------------------------------------------------------------
34      !!                 ***  ROUTINE dia_mlr_init  ***
35      !!
36      !! ** Purpose : initialisation of IOM context management for
37      !!              multiple-linear-regression analysis
38      !!
39      !!----------------------------------------------------------------------
40
41      lk_diamlr = .TRUE.
42
43      IF(lwp) THEN
44         WRITE(numout, *)
45         WRITE(numout, *) 'dia_mlr_init : initialisation of IOM context management for'
46         WRITE(numout, *) '~~~~~~~~~~~~   multiple-linear-regression analysis'
47      END IF
48
49   END SUBROUTINE dia_mlr_init
50
51   SUBROUTINE dia_mlr_iom_init
52      !!----------------------------------------------------------------------
53      !!               ***  ROUTINE dia_mlr_iom_init  ***
54      !!
55      !! ** Purpose : IOM context setup for multiple-linear-regression
56      !!              analysis
57      !!
58      !!----------------------------------------------------------------------
59
60      TYPE(xios_fieldgroup)                       ::   slxhdl_fldgrp
61      TYPE(xios_filegroup)                        ::   slxhdl_filgrp
62      TYPE(xios_field), ALLOCATABLE, DIMENSION(:) ::   slxhdl_regs, slxhdl_flds
63      TYPE(xios_field)                            ::   slxhdl_fld
64      TYPE(xios_file)                             ::   slxhdl_fil
65      LOGICAL                                     ::   slxatt_enabled
66      CHARACTER(LEN=256)                          ::   slxatt_expr
67      CHARACTER(LEN=32)                           ::   slxatt_name1,   slxatt_name2
68      CHARACTER(LEN=32)                           ::   slxatt_gridref, slxatt_fieldref
69      INTEGER, PARAMETER                          ::   jpscanmax = 999
70      INTEGER                                     ::   ireg, ifld
71      CHARACTER(LEN=3)                            ::   cl3i
72      CHARACTER(LEN=6)                            ::   cl6a
73      CHARACTER(LEN=1)                            ::   clgt
74      CHARACTER(LEN=2)                            ::   clgd
75      CHARACTER(LEN=25)                           ::   clfloat
76      CHARACTER(LEN=32)                           ::   clrepl
77      INTEGER                                     ::   jl, jm, jn
78      INTEGER                                     ::   itide                       ! Number of available tidal components
79      INTEGER,  ALLOCATABLE, DIMENSION(:)         ::   itide_const                 ! Index list of selected tidal constituents
80      REAL(wp), ALLOCATABLE, DIMENSION(:)         ::   ztide_omega, ztide_u,   &   ! Tidal frequency, phase, nodal correction
81         &                                             ztide_v, ztide_f
82      REAL(wp)                                    ::   ztide_phase                 ! Tidal-constituent phase at adatrj=0
83
84      IF(lwp) THEN
85         WRITE(numout, *)
86         WRITE(numout, *) 'dia_mlr_iom_init : IOM context setup for multiple-linear-regression'
87         WRITE(numout, *) '~~~~~~~~~~~~~~~~'
88      END IF
89
90      ! Get handles to multiple-linear-regression analysis configuration (field
91      ! group 'diamrl_fields' and file group 'diamlr_files'); if no suitable
92      ! configuration is found, disable diamlr
93      IF ( lk_diamlr .AND. xios_is_valid_fieldgroup( "diamlr_fields" ) .AND. xios_is_valid_field( "diamlr_time" ) .AND.   &
94         & xios_is_valid_filegroup( "diamlr_files" ) ) THEN
95         CALL xios_get_handle("diamlr_fields", slxhdl_fldgrp)
96         CALL xios_get_handle("diamlr_files",  slxhdl_filgrp)
97      ELSE
98         IF (lwp) THEN
99            WRITE(numout, *) "diamlr: configuration not found or icomplete (field group 'diamlr_fields'"
100            WRITE(numout, *) "        and/or file group 'diamlr_files' and/or field 'diamlr_time' missing);"
101            WRITE(numout, *) "        disabling output for multiple-linear-regression analysis."
102         END IF
103         lk_diamlr = .FALSE.
104      END IF
105
106      ! Set up IOM context for multiple-linear-regression analysis
107      IF ( lk_diamlr ) THEN
108
109         ! Set up output files for grid types scalar, grid_T, grid_U, grid_V,
110         ! and grid_W
111         DO jm = 1, 5
112            SELECT CASE( jm )
113            CASE( 1 )
114               cl6a = 'scalar'
115            CASE( 2 )
116               cl6a = 'grid_T'
117            CASE( 3 )
118               cl6a = 'grid_U'
119            CASE( 4 )
120               cl6a = 'grid_V'
121            CASE( 5 )
122               cl6a = 'grid_W'
123            END SELECT
124            CALL xios_add_child      ( slxhdl_filgrp, slxhdl_fil, "diamlr_file_"//cl6a )
125            CALL xios_set_attr       ( slxhdl_fil, name_suffix="_diamlr_"//cl6a,   &
126               &                       description="Intermediary output for multiple-linear-regression analysis - "//cl6a )
127            CALL iom_update_file_name( "diamlr_file_"//cl6a )
128         END DO
129
130         ! Compile lists of active regressors and of fields selected for
131         ! analysis (fields "diamlr_r<nnn>" and "diamlr_f<nnn>", where <nnn> is
132         ! a 3-digit integer); also carry out placeholder substitution of tidal
133         ! parameters in regressor expressions
134         !
135         ALLOCATE( slxhdl_regs( jpscanmax ), slxhdl_flds( jpscanmax ) )
136         ireg = 0
137         ifld = 0
138         !
139         ! Retrieve information (frequency, phase, nodal correction) about all
140         ! available tidal constituents for placeholder substitution below
141         itide = jpmax_harmo
142         ALLOCATE(itide_const(itide), ztide_omega(itide), ztide_u(itide), ztide_v(itide), ztide_f(itide))
143         DO jn = 1, itide
144            itide_const(jn) = jn   ! Select all available tidal constituents
145         END DO
146         CALL tide_harmo( ztide_omega, ztide_v, ztide_u, ztide_f, itide_const, itide )
147         
148         DO jm = 1, jpscanmax
149            WRITE (cl3i, '(i3.3)') jm
150
151            ! Look for regressor
152            IF ( xios_is_valid_field( "diamlr_r"//cl3i ) ) THEN
153
154               CALL xios_get_handle( "diamlr_r"//cl3i, slxhdl_regs(ireg+1) )
155               ! Retrieve pre-configured value of "enabled" attribute and
156               ! regressor expression
157               CALL xios_get_attr  ( slxhdl_regs(ireg+1), enabled=slxatt_enabled, expr=slxatt_expr )
158               ! If enabled, keep handle in list of active regressors; also
159               ! substitute placeholders for tidal frequencies, phases, and
160               ! nodal corrections in regressor expressions
161               IF ( slxatt_enabled ) THEN
162
163                  ! Substitution of placeholders for tidal-constituent
164                  ! parameters (amplitudes, angular veloccities, nodal phase
165                  ! correction) with values that have been obtained from the
166                  ! tidal-forcing implementation
167                  DO jn = 1, itide
168                     ! Compute phase of tidal constituent (incl. current nodal
169                     ! correction) at the start of the model run (i.e. for
170                     ! adatrj=0)
171                     ztide_phase = MOD( ztide_u(jn) +  ztide_v(jn) - adatrj * 86400.0_wp * ztide_omega(jn), 2.0_wp * rpi )
172                     clrepl = "__TDE_"//TRIM( Wave(jn)%cname_tide )//"_omega__"
173                     DO WHILE ( INDEX( slxatt_expr, TRIM( clrepl ) ) > 0 )
174                        WRITE (clfloat, '(e25.18)') ztide_omega(jn)
175                        jl = INDEX( slxatt_expr, TRIM( clrepl ) )
176                        slxatt_expr = slxatt_expr(1:jl - 1)//clfloat//slxatt_expr(jl + LEN( TRIM( clrepl ) ):LEN( TRIM( slxatt_expr ) ))
177                     END DO
178                     clrepl = "__TDE_"//TRIM( Wave(jn)%cname_tide )//"_phase__"
179                     DO WHILE ( INDEX( slxatt_expr, TRIM( clrepl ) ) > 0 )
180                        WRITE (clfloat, '(e25.18)') ztide_phase
181                        jl = INDEX( slxatt_expr, TRIM( clrepl ) )
182                        slxatt_expr = slxatt_expr(1:jl - 1)//clfloat//slxatt_expr(jl + LEN( TRIM( clrepl ) ):LEN( TRIM( slxatt_expr ) ))
183                     END DO
184                     clrepl = "__TDE_"//TRIM( Wave(jn)%cname_tide )//"_amplitude__"
185                     DO WHILE (INDEX( slxatt_expr, TRIM( clrepl ) ) > 0 )
186                        WRITE (clfloat, '(e25.18)') ztide_f(jn)
187                        jl = INDEX( slxatt_expr, TRIM( clrepl ) )
188                        slxatt_expr = slxatt_expr(1:jl - 1)//clfloat//slxatt_expr(jl + LEN( TRIM( clrepl ) ):LEN( TRIM( slxatt_expr ) ))
189                     END DO
190                  END DO
191
192                  ! Set name attribute (and overwrite possible pre-configured name)
193                  ! with field id to enable id string retrieval from stored handle
194                  ! below; also re-set expression with possible substitutions
195                  CALL xios_set_attr  ( slxhdl_regs(ireg+1), name="diamlr_r"//cl3i, expr=TRIM( slxatt_expr ) )
196
197                  ireg = ireg + 1   ! Accept regressor in list of active regressors
198
199               END IF
200            END IF
201
202            ! Look for field
203            IF ( xios_is_valid_field( "diamlr_f"//cl3i ) ) THEN
204
205               CALL xios_get_handle( "diamlr_f"//cl3i, slxhdl_flds(ifld+1) )
206               ! Retrieve pre-configured value of "enabled" attribute
207               CALL xios_get_attr  ( slxhdl_flds(ifld+1), enabled=slxatt_enabled )
208               ! If enabled, keep handle in list of fields selected for analysis
209               IF ( slxatt_enabled ) THEN
210                 
211                  ! Set name attribute (and overwrite possible pre-configured name)
212                  ! with field id to enable id string retrieval from stored handle
213                  ! below
214                  CALL xios_set_attr  ( slxhdl_flds(ifld+1), name="diamlr_f"//cl3i )
215
216                  ifld = ifld + 1   ! Accept field in list of fields selected for analysis
217
218               END IF
219            END IF
220
221         END DO
222
223         ! Release tidal data
224         DEALLOCATE( itide_const, ztide_omega, ztide_u, ztide_v, ztide_f )
225
226         ! Output number of active regressors and fields selected for analysis
227         IF ( lwp ) WRITE(numout,'(a,i3,a)' ) 'diamlr: ', ireg, ' active regressors found'
228         IF ( lwp ) WRITE(numout,'(a,i3,a)' ) 'diamlr: ', ifld, ' fields selected for analysis'
229
230         ! For each active regressor:
231         DO jm = 1, ireg
232
233            !   i) set up 2-dimensional and 3-dimensional versions of the
234            !      regressors; explicitely set "enabled" attribute; note, while
235            !      the scalar versions of regressors are part of the
236            !      configuration, the respective 2-dimensional versions take
237            !      over the defining expression, while the scalar and
238            !      3-dimensional versions are simply obtained via grid
239            !      transformations from the 2-dimensional version.
240            CALL xios_get_attr  ( slxhdl_regs( jm ), name=slxatt_name1, expr=slxatt_expr, enabled=slxatt_enabled )
241            CALL xios_add_child ( slxhdl_fldgrp, slxhdl_fld, TRIM( slxatt_name1 )//"_2D" )
242            CALL xios_set_attr  ( slxhdl_fld, expr=TRIM( slxatt_expr ), grid_ref="diamlr_grid_2D",     &
243               &                  field_ref="diamlr_time", enabled=slxatt_enabled )
244            CALL xios_add_child ( slxhdl_fldgrp, slxhdl_fld, TRIM( slxatt_name1 )//"_3D")
245            CALL xios_set_attr  ( slxhdl_fld, expr="this", grid_ref="diamlr_grid_2D_to_3D",            &
246               &                  field_ref=TRIM( slxatt_name1 )//"_2D", enabled=slxatt_enabled)
247            CALL xios_set_attr  ( slxhdl_regs(jm), expr="this", grid_ref="diamlr_grid_2D_to_scalar",   &
248               &                  field_ref=TRIM( slxatt_name1 )//"_2D", enabled=slxatt_enabled)
249
250            !  ii) set up definitions for the output of scalar products with
251            !      itself and with other active regressors
252            CALL xios_get_attr  ( slxhdl_regs(jm), name=slxatt_name1 )
253            CALL xios_get_handle( "diamlr_file_scalar", slxhdl_fil)
254            DO jn = 1, jm
255               ! Field for product between regressors
256               CALL xios_get_attr  ( slxhdl_regs(jn), name=slxatt_name2, enabled=slxatt_enabled )
257               CALL xios_add_child ( slxhdl_fldgrp, slxhdl_fld, TRIM( slxatt_name1 )//"."//TRIM( slxatt_name2 ) )
258               ! Set appropriate name attribute to avoid the possibility of
259               ! using an inappropriate inherited name attribute as the variable
260               ! name in the output file
261               CALL xios_set_attr  ( slxhdl_fld, name=TRIM( slxatt_name1 )//"."//TRIM( slxatt_name2 ),      &
262                  &                  grid_ref="diamlr_grid_scalar", expr="this * "//TRIM( slxatt_name2 ),   &
263                  &                  field_ref=TRIM( slxatt_name1 ), enabled=slxatt_enabled, operation="accumulate")
264               ! Add regressor-product field to output file
265               CALL xios_add_child ( slxhdl_fil, slxhdl_fld, TRIM( slxatt_name1 )//"."//TRIM( slxatt_name2 ) )
266            END DO
267
268            ! iii) set up definitions for the output of scalar products with
269            !      fields selected for analysis
270            DO jn = 1, ifld
271               CALL xios_get_attr( slxhdl_flds(jn), name=slxatt_name2, grid_ref=slxatt_gridref, field_ref=slxatt_fieldref )
272               clgt="T"
273               IF ( INDEX( slxatt_gridref, "_U_" ) > 0 ) clgt="U"
274               IF ( INDEX( slxatt_gridref, "_V_" ) > 0 ) clgt="V"
275               IF ( INDEX( slxatt_gridref, "_W_" ) > 0 ) clgt="W"
276               clgd="2D"
277               IF ( INDEX( slxatt_gridref, "_3D" ) > 0 ) clgd="3D"
278               CALL xios_add_child ( slxhdl_fldgrp, slxhdl_fld, TRIM( slxatt_name2 )//"."//TRIM( slxatt_name1 ) )
279               ! Set appropriate name attribute to avoid the possibility of
280               ! using an inappropriate inherited name attribute as the variable
281               ! name in the output file
282               CALL xios_set_attr  ( slxhdl_fld, name=TRIM( slxatt_name2 )//"."//TRIM( slxatt_name1 ),         &
283                  &                  expr="this * "//TRIM( slxatt_fieldref ), grid_ref="diamlr_grid_"//clgd,   &
284                  &                  field_ref=TRIM( slxatt_name1 )//"_"//clgd, enabled=slxatt_enabled, operation="accumulate" )
285               CALL xios_get_handle( "diamlr_file_grid_"//clgt, slxhdl_fil )
286               CALL xios_add_child ( slxhdl_fil, slxhdl_fld, TRIM( slxatt_name2 )//"."//TRIM( slxatt_name1 ) )
287            END DO
288
289         END DO
290
291         ! Release list of active regressors and fields selected for analysis
292         DEALLOCATE( slxhdl_regs, slxhdl_flds )
293
294      END IF
295
296   END SUBROUTINE dia_mlr_iom_init
297
298   SUBROUTINE dia_mlr
299      !!----------------------------------------------------------------------
300      !!                   ***  ROUTINE dia_mlr  ***
301      !!
302      !! ** Purpose : update time used in multiple-linear-regression analysis
303      !!
304      !!----------------------------------------------------------------------
305
306      REAL(wp), DIMENSION(jpi,jpj) ::   zadatrj2d
307
308      IF( ln_timing )   CALL timing_start('dia_mlr')
309
310      ! Update time to the continuous time since the start of the model run
311      ! (value of adatrj converted to time in units of seconds)
312      !
313      ! A 2-dimensional field of constant value is sent, and subsequently used
314      ! directly or transformed to a scalar or a constant 3-dimensional field as
315      ! required.
316      zadatrj2d(:,:) = adatrj*86400.0_wp
317      IF ( iom_use('diamlr_time') ) CALL iom_put('diamlr_time', zadatrj2d)
318     
319      IF( ln_timing )   CALL timing_stop('dia_mlr')
320
321   END SUBROUTINE dia_mlr
322
323END MODULE diamlr
Note: See TracBrowser for help on using the repository browser.