FV3 Bundle
ODPS_Predictor_Define.f90
Go to the documentation of this file.
1 !
2 ! ODPS_Predictor_Define
3 !
4 ! Module defining the Predictor object for the ODPS algorithm and
5 ! containing routines to manipulate it.
6 !
7 ! CREATION HISTORY:
8 ! Written by: Yong Han, JCSDA, NOAA/NESDIS 20-Jun-2008
9 ! based on the content of CRTM_Predictor_Define.f90
10 !
11 ! Refactored: Paul van Delst, 27-Mar-2012
12 ! paul.vandelst@noaa.gov
13 !
14 
16 
17  ! ------------------
18  ! Environment set up
19  ! ------------------
20  ! Module use
21  USE type_kinds , ONLY: fp
23  USE compare_float_numbers, ONLY: OPERATOR(.equalto.)
28  USE pafv_define , ONLY: pafv_type , &
30  pafv_destroy , &
32  ! Disable implicit typing
33  IMPLICIT NONE
34 
35 
36  ! ------------
37  ! Visibilities
38  ! ------------
39  ! Everything private by default
40  PRIVATE
41 
42  ! Local entities
43  ! ...Datatypes
44  PUBLIC :: odps_predictor_type
45 ! ! ...Operators
46 ! PUBLIC :: OPERATOR(==)
47  ! ...Procedures
49  PUBLIC :: odps_predictor_destroy
50  PUBLIC :: odps_predictor_create
51  PUBLIC :: odps_predictor_inspect
52  PUBLIC :: odps_predictor_zero
53 ! PUBLIC :: ODPS_Predictor_ValidRelease
54 ! PUBLIC :: ODPS_Predictor_Info
55 ! PUBLIC :: ODPS_Predictor_DefineVersion
56 ! PUBLIC :: ODPS_Predictor_InquireFile
57 ! PUBLIC :: ODPS_Predictor_ReadFile
58 ! PUBLIC :: ODPS_Predictor_WriteFile
59  ! ...Parameter
60  PUBLIC :: max_optran_order
61  PUBLIC :: max_optran_predictors
63 
64  ! USE-associated entities to pass through
65  ! ...Datatypes
66  PUBLIC :: pafv_type
67  ! ...Procedures
68  PUBLIC :: pafv_associated
69  PUBLIC :: pafv_destroy
70  PUBLIC :: pafv_create
71 
72 
73  ! ---------------------
74  ! Procedure overloading
75  ! ---------------------
76 ! INTERFACE OPERATOR(==)
77 ! MODULE PROCEDURE ODPS_Predictor_Equal
78 ! END INTERFACE OPERATOR(==)
79 
80 
81  ! -----------------
82  ! Module parameters
83  ! -----------------
84  CHARACTER(*), PARAMETER :: module_version_id = &
85  '$Id: xODPS_Predictor_Define.f90 18500 2012-04-02 11:07:35Z paul.vandelst@noaa.gov $'
86  ! Release and version
87  INTEGER, PARAMETER :: odps_predictor_release = 2 ! This determines structure and file formats.
88  INTEGER, PARAMETER :: odps_predictor_version = 1 ! This is just the default data version.
89  ! Close status for write errors
90  CHARACTER(*), PARAMETER :: write_error_status = 'DELETE'
91  ! Literal constants
92  REAL(fp), PARAMETER :: zero = 0.0_fp
93  REAL(fp), PARAMETER :: one = 1.0_fp
94  ! String lengths
95  INTEGER, PARAMETER :: ml = 256
96  ! C-OPTRAN max. order and number of predictors
97  INTEGER, PARAMETER :: max_optran_order = 10
98  INTEGER, PARAMETER :: max_optran_predictors = 14
99  INTEGER, PARAMETER :: max_optran_used_predictors = 6
100 
101 
102  ! -----------------------------------
103  ! ODPS_Predictor data type definition
104  ! -----------------------------------
105  !:tdoc+:
107  ! Allocation indicator
108  LOGICAL :: is_allocated = .false.
109  ! Release and version information
110  INTEGER :: release = odps_predictor_release
111  INTEGER :: version = odps_predictor_version
112  ! Dimension variables
113  INTEGER :: max_n_layers = 0 ! K - maximum number of layers
114  INTEGER :: n_layers = 0 ! K - actual number of layers
115  INTEGER :: n_user_layers = 0 ! Ku - number of layers of user input profile
116  INTEGER :: n_components = 0 ! J - number of tau components
117  INTEGER :: n_predictors = 0 ! I - predictor dimension (Maximum)
118  ! Scalars
119  REAL(fp) :: secant_zenith_surface ! Secant zenith angle at the surface
120  REAL(fp) :: u, v, w ! Algorithm specific variables
121  ! Arrays
122  REAL(fp), ALLOCATABLE :: secant_zenith(:) ! K ; secant zenith angle
123  INTEGER, ALLOCATABLE :: component_id(:) ! J ; Tau component Id
124  INTEGER, ALLOCATABLE :: n_cp(:) ! J ; No. of predictors for each component
125  REAL(fp), ALLOCATABLE :: x(:,:,:) ! K x I x J ; Predictor array
126  REAL(fp), ALLOCATABLE :: ref_level_lnpressure(:) ! 0:K ; Pressure arrays used for optical
127  REAL(fp), ALLOCATABLE :: user_level_lnpressure(:) ! 0:Ku; path profile interpolation
128  ! Compact-OPTRAN predictors
129  LOGICAL :: optran = .false.
130  INTEGER :: n_opredictors = 0 ! OI
131  REAL(fp), ALLOCATABLE :: ap(:,:) ! MAX_OPTRAN_ORDER x K; polynomial of the water vapor absorber level
132  REAL(fp), ALLOCATABLE :: da(:) ! K ; slant path layer integrated amount
133  REAL(fp), ALLOCATABLE :: ox(:,:) ! K x OI ; Predictor array
134  ! Structure variable to hold predictor and absorption
135  ! forward variables across FWD, TL and AD calls. It
136  ! should be allocated only for the FWD Predictor variable.
137  TYPE(pafv_type) :: pafv
138  END TYPE odps_predictor_type
139  !:tdoc-:
140 
141 
142 CONTAINS
143 
144 
145 !--------------------------------------------------------------------------------
146 !:sdoc+:
147 !
148 ! NAME:
149 ! ODPS_Predictor_Associated
150 !
151 ! PURPOSE:
152 ! Elemental function to test the status of the allocatable components
153 ! of the ODPS_Predictor structure.
154 !
155 ! CALLING SEQUENCE:
156 ! Status = ODPS_Predictor_Associated( ODPS_Predictor )
157 !
158 ! OBJECTS:
159 ! ODPS_Predictor:
160 ! Structure which is to have its member's
161 ! status tested.
162 ! UNITS: N/A
163 ! TYPE: ODPS_Predictor_type
164 ! DIMENSION: Scalar or any rank
165 ! ATTRIBUTES: INTENT(IN)
166 !
167 ! FUNCTION RESULT:
168 ! Status:
169 ! The return value is a logical value indicating the
170 ! status of the allocated members.
171 ! .TRUE. - if the ODPS_Predictor object has been allocated.
172 ! .FALSE. - if the ODPS_Predictor object has NOT been allocated.
173 ! UNITS: N/A
174 ! TYPE: LOGICAL
175 ! DIMENSION: Same as input
176 !
177 !:sdoc-:
178 !--------------------------------------------------------------------------------
179 
180  ELEMENTAL FUNCTION odps_predictor_associated( self ) RESULT( Status )
181  TYPE(odps_predictor_type), INTENT(IN) :: self
182  LOGICAL :: status
183  status = self%Is_Allocated
184  END FUNCTION odps_predictor_associated
185 
186 
187 !--------------------------------------------------------------------------------
188 !:sdoc+:
189 !
190 ! NAME:
191 ! ODPS_Predictor_Destroy
192 !
193 ! PURPOSE:
194 ! Elemental subroutine to re-initialize ODPS_Predictor objects.
195 !
196 ! CALLING SEQUENCE:
197 ! CALL ODPS_Predictor_Destroy( ODPS_Predictor )
198 !
199 ! OBJECTS:
200 ! ODPS_Predictor:
201 ! Re-initialized ODPS_Predictor structure.
202 ! UNITS: N/A
203 ! TYPE: ODPS_Predictor_type
204 ! DIMENSION: Scalar or any rank
205 ! ATTRIBUTES: INTENT(OUT)
206 !
207 !:sdoc-:
208 !--------------------------------------------------------------------------------
209 
210  ELEMENTAL SUBROUTINE odps_predictor_destroy( self )
211  TYPE(odps_predictor_type), INTENT(OUT) :: self
212  self%Is_Allocated = .false.
213  END SUBROUTINE odps_predictor_destroy
214 
215 
216 !--------------------------------------------------------------------------------
217 !:sdoc+:
218 !
219 ! NAME:
220 ! ODPS_Predictor_Create
221 !
222 ! PURPOSE:
223 ! Elemental subroutine to create an instance of an ODPS_Predictor object.
224 !
225 ! CALLING SEQUENCE:
226 ! CALL ODPS_Predictor_Create( &
227 ! ODPS_Predictor, &
228 ! n_Layers , &
229 ! n_User_Layers , &
230 ! n_Components , &
231 ! n_Predictors , &
232 ! No_OPTRAN = No_OPTRAN )
233 !
234 ! OBJECTS:
235 ! ODPS_Predictor:
236 ! ODPS_Predictor object structure.
237 ! UNITS: N/A
238 ! TYPE: ODPS_Predictor_type
239 ! DIMENSION: Scalar or any rank
240 ! ATTRIBUTES: INTENT(OUT)
241 !
242 ! INPUTS:
243 ! n_Layers:
244 ! Number of atmospheric layers.
245 ! Must be > 0.
246 ! UNITS: N/A
247 ! TYPE: INTEGER
248 ! DIMENSION: Conformable with the ODPS_Predictor object
249 ! ATTRIBUTES: INTENT(IN)
250 !
251 ! n_Components:
252 ! Number of atmospheric absorption components.
253 ! Must be > 0.
254 ! UNITS: N/A
255 ! TYPE: INTEGER
256 ! DIMENSION: Conformable with the ODPS_Predictor object
257 ! ATTRIBUTES: INTENT(IN)
258 !
259 ! n_Predictors:
260 ! Maximum number of absorption predictor.
261 ! Must be > 0.
262 ! UNITS: N/A
263 ! TYPE: INTEGER
264 ! DIMENSION: Conformable with the ODPS_Predictor object
265 ! ATTRIBUTES: INTENT(IN)
266 !
267 ! OPTIONAL INPUTS:
268 ! No_OPTRAN:
269 ! Logical switch to disable allocation of Compact-OPTRAN
270 ! arrays for use with water vapour absorption.
271 ! If == .FALSE., arrays are allocated [DEFAULT]
272 ! == .TRUE., arrays are NOT allocated
273 ! If not specified, arrays are allocated.
274 ! UNITS: N/A
275 ! TYPE: LOGICAL
276 ! DIMENSION: Conformable with the ODPS_Predictor object
277 ! ATTRIBUTES: INTENT(IN), OPTIONAL
278 !
279 !:sdoc-:
280 !--------------------------------------------------------------------------------
281 
282  ELEMENTAL SUBROUTINE odps_predictor_create( &
283  self , & ! Output
284  n_Layers , & ! Input
285  n_User_Layers, & ! Input
286  n_Components , & ! Input
287  n_Predictors , & ! Input
288  No_OPTRAN ) ! Optional Input
289  ! Arguments
290  TYPE(odps_predictor_type), INTENT(OUT) :: self
291  INTEGER, INTENT(IN) :: n_layers
292  INTEGER, INTENT(IN) :: n_user_layers
293  INTEGER, INTENT(IN) :: n_components
294  INTEGER, INTENT(IN) :: n_predictors
295  LOGICAL, OPTIONAL, INTENT(IN) :: no_optran
296  ! Local variables
297  LOGICAL :: use_optran
298  INTEGER :: alloc_stat
299 
300  ! Check input
301  IF ( n_layers < 1 .OR. &
302  n_user_layers < 1 .OR. &
303  n_components < 1 .OR. &
304  n_predictors < 1 ) RETURN
305  ! ...Process options
306  use_optran = .true.
307  IF ( PRESENT(no_optran) ) use_optran = .NOT. no_optran
308 
309  ! Perform the allocation
310  ALLOCATE( self%Secant_Zenith(n_layers), &
311  self%Component_ID(n_components), &
312  self%n_CP(n_components), &
313  self%X(n_layers, n_predictors, n_components), &
314  self%Ref_Level_LnPressure(0:n_layers), &
315  self%User_Level_LnPressure(0:n_user_layers), &
316  stat = alloc_stat )
317  IF ( alloc_stat /= 0 ) RETURN
318 
319 
320  ! Initialise dimensions
321  self%Max_n_Layers = n_layers
322  self%n_Layers = n_layers
323  self%n_User_Layers = n_user_layers
324  self%n_Components = n_components
325  self%n_Predictors = n_predictors
326 
327 
328  ! Allocate OPTRAN if required
329  IF ( use_optran ) THEN
330  ALLOCATE( self%OX(n_layers, max_optran_predictors), &
331  self%Ap(n_layers, max_optran_order), &
332  self%dA(n_layers), &
333  stat = alloc_stat )
334  IF ( alloc_stat /= 0 ) RETURN
335  ! Initialise dimensions
336  self%n_OPredictors = max_optran_predictors
337  ! ...Flag OPTRAN section as usuable
338  self%OPTRAN = .true.
339  END IF
340 
341 
342  ! Set allocation indicator
343  self%Is_Allocated = .true.
344 
345 
346  ! Initialise array data
347  CALL odps_predictor_zero(self)
348 
349  END SUBROUTINE odps_predictor_create
350 
351 
352 !--------------------------------------------------------------------------------
353 !:sdoc+:
354 !
355 ! NAME:
356 ! ODPS_Predictor_Inspect
357 !
358 ! PURPOSE:
359 ! Subroutine to print the contents of a ODPS_Predictor object to stdout.
360 !
361 ! CALLING SEQUENCE:
362 ! CALL ODPS_Predictor_Inspect( ODPS_Predictor )
363 !
364 ! OBJECTS:
365 ! ODPS_Predictor:
366 ! ODPS_Predictor object to display.
367 ! UNITS: N/A
368 ! TYPE: ODPS_Predictor_type
369 ! DIMENSION: Scalar
370 ! ATTRIBUTES: INTENT(IN)
371 !
372 !:sdoc-:
373 !--------------------------------------------------------------------------------
374 
375  SUBROUTINE odps_predictor_inspect(self)
376  TYPE(odps_predictor_type), INTENT(IN) :: self
377  INTEGER :: i, j
378  WRITE(*,'(1x,"ODPS_Predictor OBJECT")')
379  ! Release/version info
380  WRITE(*,'(3x,"Release.Version :",1x,i0,".",i0)') self%Release, self%Version
381  ! Dimensions
382  WRITE(*,'(3x,"n_Layers :",1x,i0)') self%n_Layers
383  WRITE(*,'(3x,"n_User_Layers :",1x,i0)') self%n_User_Layers
384  WRITE(*,'(3x,"n_Components :",1x,i0)') self%n_Components
385  WRITE(*,'(3x,"n_Predictors :",1x,i0)') self%n_Predictors
386  IF ( .NOT. odps_predictor_associated(self) ) RETURN
387  ! ODPS data arrays
388  WRITE(*,'(3x,"ODPS data arrays :")')
389  ! ...ODPS Forward variables
390  WRITE(*,'(5x,"Secant_Zenith :")')
391  WRITE(*,'(5(1x,es23.15e3,:))') self%Secant_Zenith(1:self%n_Layers)
392  WRITE(*,'(5x,"Component_ID :")')
393  WRITE(*,'(10(1x,i0,:))') self%Component_ID(1:self%n_Components)
394  WRITE(*,'(5x,"n_CP :")')
395  WRITE(*,'(10(1x,i0,:))') self%n_CP(1:self%n_Components)
396  WRITE(*,'(5x,"X (predictor array) :")')
397  DO j = 1, self%n_Components
398  DO i = 1, self%n_Predictors
399  WRITE(*,'(7x,"Component#: ",i0,"; Predictor#: ",i0)') j, i
400  WRITE(*,'(5(1x,es23.15e3,:))') self%X(1:self%n_Layers,i,j)
401  END DO
402  WRITE(*,*)
403  END DO
404  ! ...Pressure profiles for interpolations
405  WRITE(*,'(5x,"Ref_Level_LnPressure :")')
406  WRITE(*,'(5(1x,es13.6,:))') self%Ref_Level_LnPressure
407  WRITE(*,'(5x,"User_Level_LnPressure :")')
408  WRITE(*,'(5(1x,es13.6,:))') self%User_Level_LnPressure
409  ! Compact-OPTRAN Forward variables
410  IF ( self%OPTRAN ) THEN
411  WRITE(*,'(3x,"n_OPredictors :",1x,i0)') self%n_OPredictors
412  WRITE(*,'(5x,"OX :")'); WRITE(*,'(5(1x,es13.6,:))') self%OX
413  WRITE(*,'(5x,"Ap :")'); WRITE(*,'(5(1x,es13.6,:))') self%Ap
414  WRITE(*,'(5x,"dA :")'); WRITE(*,'(5(1x,es13.6,:))') self%dA
415  END IF
416  END SUBROUTINE odps_predictor_inspect
417 
418 
419 !--------------------------------------------------------------------------------
420 !:sdoc+:
421 !
422 ! NAME:
423 ! ODPS_Predictor_Zero
424 !
425 ! PURPOSE:
426 ! Elementl subroutine to zero-out an instance of an ODPS predictor object.
427 !
428 ! CALLING SEQUENCE:
429 ! CALL ODPS_Predictor_Zero( ODPS_Predictor )
430 !
431 ! OUTPUTS:
432 ! ODPS_Predictor:
433 ! ODPS_Predictor object structure.
434 ! UNITS: N/A
435 ! TYPE: ODPS_Predictor_type
436 ! DIMENSION: Scalar or any rank
437 ! ATTRIBUTES: INTENT(IN OUT)
438 !
439 !:sdoc-:
440 !--------------------------------------------------------------------------------
441 
442  ELEMENTAL SUBROUTINE odps_predictor_zero( self )
443  TYPE(odps_predictor_type), INTENT(IN OUT) :: self
444  IF ( .NOT. odps_predictor_associated(self) ) RETURN
445  self%Secant_Zenith = zero
446  self%Component_ID = 0
447  self%n_CP = self%n_Predictors
448  self%X = zero
449  self%Ref_Level_LnPressure = zero
450  self%User_Level_LnPressure = zero
451  IF ( self%OPTRAN ) THEN
452  self%OX = zero
453  self%Ap = zero
454  self%dA = zero
455  END IF
456  END SUBROUTINE odps_predictor_zero
457 
458 END MODULE odps_predictor_define
character(*), parameter module_version_id
integer, parameter, public failure
real(fp), parameter, public zero
integer, parameter, public max_optran_used_predictors
integer, parameter, public fp
Definition: Type_Kinds.f90:124
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
integer, parameter odps_predictor_version
elemental subroutine, public pafv_create(self, n_ODPS_Layers, n_User_Layers, n_Absorbers, No_OPTRAN)
elemental subroutine, public odps_predictor_zero(self)
elemental subroutine, public odps_predictor_destroy(self)
subroutine, public odps_predictor_inspect(self)
character(*), parameter write_error_status
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
real(fp), parameter, public one
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
elemental logical function, public pafv_associated(self)
integer, parameter odps_predictor_release
elemental subroutine, public odps_predictor_create(self, n_Layers, n_User_Layers, n_Components, n_Predictors, No_OPTRAN)
integer, parameter, public max_optran_predictors
integer, parameter, public max_n_layers
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
elemental logical function, public odps_predictor_associated(self)
elemental subroutine, public pafv_destroy(self)
integer, parameter, public success
integer, parameter, public information
integer, parameter, public max_optran_order