FV3 Bundle
NLTE_Predictor_Define.f90
Go to the documentation of this file.
1 !
2 ! NLTE_Predictor_Define
3 !
4 ! Module defining the NLTE_Predictor data structure and containing routines to
5 ! manipulate it.
6 !
7 ! CREATION HISTORY:
8 ! Written by: Paul van Delst, 16-Mar-2011
9 ! paul.vandelst@noaa.gov
10 !
11 
13 
14  ! ------------------
15  ! Environment set up
16  ! ------------------
17  ! Module use
18  USE type_kinds, ONLY: fp
21  OPERATOR(.equalto.), &
24  ! Disable implicit typing
25  IMPLICIT NONE
26 
27 
28  ! ------------
29  ! Visibilities
30  ! ------------
31  ! Everything private by default
32  PRIVATE
33  ! Datatypes
34  PUBLIC :: nlte_predictor_type
35  ! Operators
36  PUBLIC :: OPERATOR(==)
37  ! Procedures
38  PUBLIC :: nlte_predictor_destroy
39  PUBLIC :: nlte_predictor_inspect
41  PUBLIC :: nlte_predictor_info
43  PUBLIC :: nlte_predictor_compare
44  PUBLIC :: nlte_predictor_isactive
45 
46 
47  ! ---------------------
48  ! Procedure overloading
49  ! ---------------------
50  INTERFACE OPERATOR(==)
51  MODULE PROCEDURE nlte_predictor_equal
52  END INTERFACE OPERATOR(==)
53 
54 
55  ! -----------------
56  ! Module parameters
57  ! -----------------
58  ! Version Id for the module
59  CHARACTER(*), PARAMETER :: module_version_id = &
60  '$Id: NLTE_Predictor_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
61  ! Literal constants
62  REAL(fp), PARAMETER :: zero = 0.0_fp
63  REAL(fp), PARAMETER :: one = 1.0_fp
64  ! Default message string length
65  INTEGER, PARAMETER :: ml = 512
66  ! Sensor id string length
67  INTEGER, PARAMETER :: sl = 20
68  ! Current valid release and version numbers
69  INTEGER, PARAMETER :: nlte_predictor_release = 1
70  INTEGER, PARAMETER :: nlte_predictor_version = 1
71 
72 
73  ! -----------------------
74  ! Derived type definition
75  ! -----------------------
77  ! Allocation indicator
78  LOGICAL :: is_allocated = .true.
79  ! Release and version information
80  INTEGER :: release = nlte_predictor_release
81  INTEGER :: version = nlte_predictor_version
82  ! Dimensions
83  INTEGER :: n_layers = n_nlte_layers
84  INTEGER :: n_predictors = n_nlte_layers + 1
85  ! Logical indicators
86  ! ...In-use indicator
87  LOGICAL :: is_active = .false.
88  ! ...Computation indicator
89  LOGICAL :: compute_tm = .true.
90  ! Data
91  INTEGER :: k1(n_nlte_layers) = 0 ! Indices of atmosphere for upper layer
92  INTEGER :: k2(n_nlte_layers) = 0 ! Indices of atmosphere for lower layer
93  INTEGER :: isen = 0 ! Indices of coefficients for user sensor zenith angle
94  INTEGER :: isol = 0 ! Indices of coefficients for user solar zenith angle
95  REAL(fp) :: tm(n_nlte_layers) = zero ! Mean layer temperature
96  REAL(fp) :: predictor(n_nlte_layers + 1) = zero ! Predictors
97  REAL(fp) :: w(2, 2) = zero ! Coefficient bilinear interpolation weights
98  END TYPE nlte_predictor_type
99 
100 
101 CONTAINS
102 
103 
104 !################################################################################
105 !################################################################################
106 !## ##
107 !## ## PUBLIC MODULE ROUTINES ## ##
108 !## ##
109 !################################################################################
110 !################################################################################
111 
112 !--------------------------------------------------------------------------------
113 !:sdoc+:
114 !
115 ! NAME:
116 ! NLTE_Predictor_Destroy
117 !
118 ! PURPOSE:
119 ! Elemental subroutine to re-initialize NLTE_Predictor objects.
120 !
121 ! CALLING SEQUENCE:
122 ! CALL NLTE_Predictor_Destroy( NLTE_Predictor )
123 !
124 ! OBJECTS:
125 ! NLTE_Predictor: Re-initialized NLTE_Predictor structure.
126 ! UNITS: N/A
127 ! TYPE: NLTE_Predictor_type
128 ! DIMENSION: Scalar or any rank
129 ! ATTRIBUTES: INTENT(OUT)
130 !
131 !:sdoc-:
132 !--------------------------------------------------------------------------------
133 
134  ELEMENTAL SUBROUTINE nlte_predictor_destroy( NLTE_Predictor )
135  TYPE(nlte_predictor_type), INTENT(OUT) :: nlte_predictor
136  ! Set logicals to avoid "unused argument" warnings
137  nlte_predictor%Is_Active = .false.
138  nlte_predictor%Compute_Tm = .true.
139  END SUBROUTINE nlte_predictor_destroy
140 
141 
142 !--------------------------------------------------------------------------------
143 !:sdoc+:
144 !
145 ! NAME:
146 ! NLTE_Predictor_Inspect
147 !
148 ! PURPOSE:
149 ! Subroutine to print the contents of a NLTE_Predictor object to stdout.
150 !
151 ! CALLING SEQUENCE:
152 ! CALL NLTE_Predictor_Inspect( NLTE_Predictor )
153 !
154 ! OBJECTS:
155 ! NLTE_Predictor: NLTE_Predictor object to display.
156 ! UNITS: N/A
157 ! TYPE: NLTE_Predictor_type
158 ! DIMENSION: Scalar
159 ! ATTRIBUTES: INTENT(IN)
160 !
161 !:sdoc-:
162 !--------------------------------------------------------------------------------
163 
164  SUBROUTINE nlte_predictor_inspect( NLTE_Predictor )
165  TYPE(nlte_predictor_type), INTENT(IN) :: nlte_predictor
166  WRITE(*,'(1x,"NLTE_Predictor OBJECT")')
167  ! Release/version info
168  WRITE(*,'(3x,"Release.Version :",1x,i0,".",i0)') nlte_predictor%Release, nlte_predictor%Version
169  ! Dimensions
170  WRITE(*,'(3x,"n_Layers :",1x,i0)') nlte_predictor%n_Layers
171  WRITE(*,'(3x,"n_Predictors :",1x,i0)') nlte_predictor%n_Predictors
172  ! Logical indicators
173  WRITE(*,'(3x,"Is_Active :",1x,l1)') nlte_predictor%Is_Active
174  WRITE(*,'(3x,"Compute_Tm :",1x,l1)') nlte_predictor%Compute_Tm
175  ! Data
176  WRITE(*,'(3x,"k1 :",4(1x,i0,:,","))') nlte_predictor%k1
177  WRITE(*,'(3x,"k2 :",4(1x,i0,:,","))') nlte_predictor%k2
178  WRITE(*,'(3x,"isen :",1x,i0)') nlte_predictor%isen
179  WRITE(*,'(3x,"isol :",1x,i0)') nlte_predictor%isol
180  WRITE(*,'(3x,"Tm :")')
181  WRITE(*,'(5(1x,es13.6,:))') nlte_predictor%Tm
182  WRITE(*,'(3x,"Predictor :")')
183  WRITE(*,'(5(1x,es13.6,:))') nlte_predictor%Predictor
184  WRITE(*,'(3x,"w :")')
185  WRITE(*,'(5(1x,es13.6,:))') nlte_predictor%w
186 
187  END SUBROUTINE nlte_predictor_inspect
188 
189 
190 !----------------------------------------------------------------------------------
191 !:sdoc+:
192 !
193 ! NAME:
194 ! NLTE_Predictor_ValidRelease
195 !
196 ! PURPOSE:
197 ! Function to check the NLTE_Predictor Release value.
198 !
199 ! CALLING SEQUENCE:
200 ! IsValid = NLTE_Predictor_ValidRelease( NLTE_Predictor )
201 !
202 ! INPUTS:
203 ! NLTE_Predictor: NLTE_Predictor object for which the Release component
204 ! is to be checked.
205 ! UNITS: N/A
206 ! TYPE: NLTE_Predictor_type
207 ! DIMENSION: Scalar
208 ! ATTRIBUTES: INTENT(IN)
209 !
210 ! FUNCTION RESULT:
211 ! IsValid: Logical value defining the release validity.
212 ! UNITS: N/A
213 ! TYPE: LOGICAL
214 ! DIMENSION: Scalar
215 !
216 !:sdoc-:
217 !----------------------------------------------------------------------------------
218 
219  FUNCTION nlte_predictor_validrelease( NLTE_Predictor ) RESULT( IsValid )
220  ! Arguments
221  TYPE(nlte_predictor_type), INTENT(IN) :: nlte_predictor
222  ! Function result
223  LOGICAL :: isvalid
224  ! Local parameters
225  CHARACTER(*), PARAMETER :: routine_name = 'NLTE_Predictor_ValidRelease'
226  ! Local variables
227  CHARACTER(ML) :: msg
228 
229  ! Set up
230  isvalid = .true.
231 
232 
233  ! Check release is not too old
234  IF ( nlte_predictor%Release < nlte_predictor_release ) THEN
235  isvalid = .false.
236  WRITE( msg,'("An NLTE_Predictor data update is needed. ", &
237  &"NLTE_Predictor release is ",i0,". Valid release is ",i0,"." )' ) &
238  nlte_predictor%Release, nlte_predictor_release
239  CALL display_message( routine_name, msg, information )
240  RETURN
241  END IF
242 
243 
244  ! Check release is not too new
245  IF ( nlte_predictor%Release > nlte_predictor_release ) THEN
246  isvalid = .false.
247  WRITE( msg,'("An NLTE_Predictor software update is needed. ", &
248  &"NLTE_Predictor release is ",i0,". Valid release is ",i0,"." )' ) &
249  nlte_predictor%Release, nlte_predictor_release
250  CALL display_message( routine_name, msg, information )
251  RETURN
252  END IF
253 
254  END FUNCTION nlte_predictor_validrelease
255 
256 
257 !--------------------------------------------------------------------------------
258 !:sdoc+:
259 !
260 ! NAME:
261 ! NLTE_Predictor_Info
262 !
263 ! PURPOSE:
264 ! Subroutine to return a string containing version and dimension
265 ! information about a NLTE_Predictor object.
266 !
267 ! CALLING SEQUENCE:
268 ! CALL NLTE_Predictor_Info( NLTE_Predictor, Info )
269 !
270 ! OBJECTS:
271 ! NLTE_Predictor: NLTE_Predictor object about which info is required.
272 ! UNITS: N/A
273 ! TYPE: NLTE_Predictor_type
274 ! DIMENSION: Scalar
275 ! ATTRIBUTES: INTENT(IN)
276 !
277 ! OUTPUTS:
278 ! Info: String containing version and dimension information
279 ! about the NLTE_Predictor object.
280 ! UNITS: N/A
281 ! TYPE: CHARACTER(*)
282 ! DIMENSION: Scalar
283 ! ATTRIBUTES: INTENT(OUT)
284 !
285 !:sdoc-:
286 !--------------------------------------------------------------------------------
287 
288  SUBROUTINE nlte_predictor_info( NLTE_Predictor, Info )
289  ! Arguments
290  TYPE(nlte_predictor_type), INTENT(IN) :: nlte_predictor
291  CHARACTER(*), INTENT(OUT) :: info
292  ! Parameters
293  INTEGER, PARAMETER :: carriage_return = 13
294  INTEGER, PARAMETER :: linefeed = 10
295  ! Local variables
296  CHARACTER(2000) :: long_string
297 
298  ! Write the required data to the local string
299  WRITE( long_string, &
300  '(a,1x,"NLTE_Predictor RELEASE.VERSION: ",i2,".",i2.2,a,3x, &
301  &"N_LAYERS=",i0,2x,&
302  &"N_PREDICTORS=",i0 )' ) &
303  achar(carriage_return)//achar(linefeed), &
304  nlte_predictor%Release, nlte_predictor%Version, &
305  achar(carriage_return)//achar(linefeed), &
306  nlte_predictor%n_Layers , &
307  nlte_predictor%n_Predictors
308 
309  ! Trim the output based on the
310  ! dummy argument string length
311  info = long_string(1:min(len(info), len_trim(long_string)))
312 
313  END SUBROUTINE nlte_predictor_info
314 
315 
316 !--------------------------------------------------------------------------------
317 !:sdoc+:
318 !
319 ! NAME:
320 ! NLTE_Predictor_DefineVersion
321 !
322 ! PURPOSE:
323 ! Subroutine to return the module version information.
324 !
325 ! CALLING SEQUENCE:
326 ! CALL NLTE_Predictor_DefineVersion( Id )
327 !
328 ! OUTPUTS:
329 ! Id: Character string containing the version Id information
330 ! for the module.
331 ! UNITS: N/A
332 ! TYPE: CHARACTER(*)
333 ! DIMENSION: Scalar
334 ! ATTRIBUTES: INTENT(OUT)
335 !
336 !:sdoc-:
337 !--------------------------------------------------------------------------------
338 
339  SUBROUTINE nlte_predictor_defineversion( Id )
340  CHARACTER(*), INTENT(OUT) :: id
341  id = module_version_id
342  END SUBROUTINE nlte_predictor_defineversion
343 
344 
345 !------------------------------------------------------------------------------
346 !:sdoc+:
347 ! NAME:
348 ! NLTE_Predictor_Compare
349 !
350 ! PURPOSE:
351 ! Elemental function to compare two NLTE_Predictor objects to within
352 ! a user specified number of significant figures.
353 !
354 ! CALLING SEQUENCE:
355 ! is_comparable = NLTE_Predictor_Compare( x, y, n_SigFig=n_SigFig )
356 !
357 ! OBJECTS:
358 ! x, y: Two NLTE_Predictor objects to be compared.
359 ! UNITS: N/A
360 ! TYPE: NLTE_Predictor_type
361 ! DIMENSION: Scalar or any rank
362 ! ATTRIBUTES: INTENT(IN)
363 !
364 ! OPTIONAL INPUTS:
365 ! n_SigFig: Number of significant figure to compare floating point
366 ! components.
367 ! UNITS: N/A
368 ! TYPE: INTEGER
369 ! DIMENSION: Scalar or same as input
370 ! ATTRIBUTES: INTENT(IN), OPTIONAL
371 !
372 ! FUNCTION RESULT:
373 ! is_equal: Logical value indicating whether the inputs are equal.
374 ! UNITS: N/A
375 ! TYPE: LOGICAL
376 ! DIMENSION: Same as inputs.
377 !:sdoc-:
378 !------------------------------------------------------------------------------
379 
380  ELEMENTAL FUNCTION nlte_predictor_compare( &
381  x, &
382  y, &
383  n_SigFig ) &
384  result( is_comparable )
385  TYPE(nlte_predictor_type), INTENT(IN) :: x, y
386  INTEGER, OPTIONAL, INTENT(IN) :: n_sigfig
387  LOGICAL :: is_comparable
388  ! Variables
389  INTEGER :: n
390 
391  ! Set up
392  is_comparable = .false.
393  IF ( PRESENT(n_sigfig) ) THEN
394  n = abs(n_sigfig)
395  ELSE
396  n = default_n_sigfig
397  END IF
398 
399  ! Check contents
400  ! ...Release/version info
401  IF ( (x%Release /= y%Release) .OR. &
402  (x%Version /= y%Version) ) RETURN
403  ! ...Dimensions
404  IF ( (x%n_Layers /= y%n_Layers ) .OR. &
405  (x%n_Predictors /= y%n_Predictors ) ) RETURN
406  ! ...Scalars
407  IF ( (x%Is_Active .NEQV. y%Is_Active ) .OR. &
408  (x%Compute_Tm .NEQV. y%Compute_Tm) .OR. &
409  (x%isen /= y%isen ) .OR. &
410  (x%isol /= y%isol ) ) RETURN
411  ! ...Integer arrays
412  IF ( any(x%k1 /= y%k1) .AND. any(x%k2 /= y%k2) ) RETURN
413  ! ...Floating point arrays
414  IF ( (.NOT. all(compares_within_tolerance(x%Tm , y%Tm , n))) .OR. &
415  (.NOT. all(compares_within_tolerance(x%Predictor, y%Predictor, n))) .OR. &
416  (.NOT. all(compares_within_tolerance(x%w , y%w , n))) ) RETURN
417 
418  ! If we get here, the structures are comparable
419  is_comparable = .true.
420 
421  END FUNCTION nlte_predictor_compare
422 
423 
424 !------------------------------------------------------------------------------
425 !:sdoc+:
426 ! NAME:
427 ! NLTE_Predictor_IsActive
428 !
429 ! PURPOSE:
430 ! Elemental function to determine if an NLTE_Predictor object is
431 ! active and valid for use in NLTE correction.
432 !
433 ! CALLING SEQUENCE:
434 ! is_active = NLTE_Predictor_IsActive( NLTE_Predictor )
435 !
436 ! OBJECTS:
437 ! NLTE_Predictor: NLTE_Predictor object to be tested.
438 ! UNITS: N/A
439 ! TYPE: NLTE_Predictor_type
440 ! DIMENSION: Scalar or any rank
441 ! ATTRIBUTES: INTENT(IN)
442 !
443 ! FUNCTION RESULT:
444 ! is_active: Logical value indicating whether the input predictor
445 ! is active and valid for use.
446 ! UNITS: N/A
447 ! TYPE: LOGICAL
448 ! DIMENSION: Same as inputs.
449 !:sdoc-:
450 !------------------------------------------------------------------------------
451 
452  ELEMENTAL FUNCTION nlte_predictor_isactive( NLTE_Predictor ) RESULT( Is_Active )
453  TYPE(nlte_predictor_type), INTENT(IN) :: nlte_predictor
454  LOGICAL :: is_active
455  is_active = nlte_predictor%Is_Active
456  END FUNCTION nlte_predictor_isactive
457 
458 
459 !##################################################################################
460 !##################################################################################
461 !## ##
462 !## ## PRIVATE MODULE ROUTINES ## ##
463 !## ##
464 !##################################################################################
465 !##################################################################################
466 
467 !------------------------------------------------------------------------------
468 !
469 ! NAME:
470 ! NLTE_Predictor_Equal
471 !
472 ! PURPOSE:
473 ! Elemental function to test the equality of two NLTE_Predictor objects.
474 ! Used in OPERATOR(==) interface block.
475 !
476 ! CALLING SEQUENCE:
477 ! is_equal = NLTE_Predictor_Equal( x, y )
478 !
479 ! or
480 !
481 ! IF ( x == y ) THEN
482 ! ...
483 ! END IF
484 !
485 ! OBJECTS:
486 ! x, y: Two NLTE_Predictor objects to be compared.
487 ! UNITS: N/A
488 ! TYPE: NLTE_Predictor_type
489 ! DIMENSION: Scalar or any rank
490 ! ATTRIBUTES: INTENT(IN)
491 !
492 ! FUNCTION RESULT:
493 ! is_equal: Logical value indicating whether the inputs are equal.
494 ! UNITS: N/A
495 ! TYPE: LOGICAL
496 ! DIMENSION: Same as inputs.
497 !
498 !------------------------------------------------------------------------------
499 
500  ELEMENTAL FUNCTION nlte_predictor_equal( x, y ) RESULT( is_equal )
501  TYPE(nlte_predictor_type), INTENT(IN) :: x, y
502  LOGICAL :: is_equal
503 
504  ! Set up
505  is_equal = .false.
506 
507  ! Check contents
508  ! ...Release/version info
509  IF ( (x%Release /= y%Release) .OR. &
510  (x%Version /= y%Version) ) RETURN
511  ! ...Dimensions
512  IF ( (x%n_Layers /= y%n_Layers ) .OR. &
513  (x%n_Predictors /= y%n_Predictors ) ) RETURN
514  ! ...Scalars
515  IF ( (x%Is_Active .NEQV. y%Is_Active ) .OR. &
516  (x%Compute_Tm .NEQV. y%Compute_Tm) .OR. &
517  (x%isen /= y%isen ) .OR. &
518  (x%isol /= y%isol ) ) RETURN
519  ! ...Arrays
520  IF ( all(x%k1 == y%k1 ) .AND. &
521  all(x%k2 == y%k2 ) .AND. &
522  all(x%Tm .equalto. y%Tm ) .AND. &
523  all(x%Predictor .equalto. y%Predictor) .AND. &
524  all(x%w .equalto. y%w ) ) &
525  is_equal = .true.
526 
527  END FUNCTION nlte_predictor_equal
528 
529 END MODULE nlte_predictor_define
character(*), parameter module_version_id
elemental logical function, public nlte_predictor_compare(x, y, n_SigFig)
integer, parameter, public failure
elemental subroutine, public nlte_predictor_destroy(NLTE_Predictor)
real(fp), parameter, public zero
elemental logical function, public nlte_predictor_isactive(NLTE_Predictor)
integer, parameter, public fp
Definition: Type_Kinds.f90:124
integer, parameter, public n_nlte_layers
logical function, public nlte_predictor_validrelease(NLTE_Predictor)
subroutine, public nlte_predictor_info(NLTE_Predictor, Info)
elemental logical function nlte_predictor_equal(x, y)
integer, parameter, public n_nlte_predictors
real(fp), parameter, public one
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer, parameter, public default_n_sigfig
integer, parameter nlte_predictor_release
subroutine, public nlte_predictor_defineversion(Id)
integer, parameter nlte_predictor_version
subroutine, public nlte_predictor_inspect(NLTE_Predictor)
#define min(a, b)
Definition: mosaic_util.h:32
integer, parameter, public success
integer, parameter, public information