1 | MODULE 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 | !!---------------------------------------------------------------------- |
---|
30 | CONTAINS |
---|
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 | |
---|
323 | END MODULE diamlr |
---|