wiki:Documentation/UserGuide/HistoryOperators

How to understand the operations performed on the variables when written in the history files using IOIPSL

Author: F. Maignan
Last revision: C. Ottle 2020/02/28

IOIPSL/src/histcom.f90

The main information useful for ORCHIDEE is reproduced below:

histdef: The variables which will be written are declared and the following information is passed:

  • name of variable
  • title
  • units
  • size of the variable
  • operation to be carried out on the variable before writing it
  • frequency at which the operations need to be done (positive values are in units of seconds and negative values are in units of month)
  • frequency at which the output data need to be written into the file(positive values are in units of seconds and negative values are in units of month)

Allowed operations

In histdef the user may specify for each field that is going to be archived a number of operations. 3 types may be distinguished: Vector operations, vector-scalar operations and index operations on the vector. In the description of the operations to be carried out the vector will be represented by x. For instance a gather operation will be written "gather(x)". It must be noted that the indexing operations will use as index vector the one passed to histwrite. On top of this a time operation has to be chosen. There only one is allowed and it should be outer most operator. For instance the time averaging of the gather operation will be written as "ave(gather(x))".

  • Allowed time operations:
avetime average of the field
instinstantaneous values of the field is going to be written
t_minthe minimum value over the time period is going to be archived
t_maxthe maximum value over the time period is going to be archived
t_sumsums the variable over time
oncethe field is written once on the file without any time axis
neverthe field is never written
  • Allowed vector operations:

Usage: cels(x)

celstransforms the field from Kelvin into degrees Celsius
  • Allowed vector-scalar operations:

Usage: scal*x

*multiplication
  • Allowed indexing operations:

Usage: gather(x)

gatherGathers from the input data all the points listed in index and puts them onto the file. Other points in the resulting array are going to labeled as missing. This operation could be used to reduce the resolution of  the history file.
scatterScatters from the input data onto the points which are listed in the index. Other points are going to be labeled as missing. This is used for instance to put a variable only available over oceans onto a global grid.

Examples:

  • ave(scatter(cels(X)): Will average the variables (temperature for instance) in Celsius and scatter it onto the grid. This could be used in an ocean model where all grid points are in a vector and cover only ocean points. Thus in the history file you will have the field placed correctly on the map.
  • ave(max(cels(x),0.)): Average over time only the values of x (transformed from Kelvin into Celsius) which are above 0.
  • t_max(X): Computes the maximum over the time between two writes of the variable.

src_sechiba/intersurf.f90 and src_sechiba/ioipslctrl.f90

The histdef calls are made in the intsurf_history subroutine for the sechiba history file and similarly in the stom_define_history subroutine for the stomate history file.

Characters strings are first declared to perform units conversion for fluxes:

!! Operations to be performed on fluxes
CHARACTER(LEN=30)   :: flux_op     
!! Operations which do not include a scatter               
CHARACTER(LEN=30)   :: flux_sc    
!! Operation in seconds                
CHARACTER(LEN=30)   :: flux_insec, flux_scinsec 

The history level will determine the number of output variables:

!! history output level (default is 10 => maximum output)
INTEGER(i_std)     :: hist_level 

The following strings arrays will contain the operation to perform from 1 to hist_level and contain ‘never’ from hist_level to 10, meaning there is nothing to do (the variable is not written in the history file).

!! The various operations to be performed
CHARACTER(LEN=40),DIMENSION(max_hist_level) :: &
         & ave, avecels, avescatter, fluxop, &
         & fluxop_scinsec, tmincels, tmaxcels, once, sumscatter  

For fluxes, the operation is written as a string with IOIPSL operators including a multiplication by the number required to obtain the desired output unit:

WRITE(flux_op,'("ave(scatter(X*",F8.1,"))")') one_day/dt
WRITE(flux_sc,'("ave(X*",F8.1,")")') one_day/dt
WRITE(flux_insec,'("ave(X*",F8.6,")")') un/dt
WRITE(flux_scinsec,'("ave(scatter(X*",F8.6,"))")') un/dt

Reading of the chosen history level from the run.def file:

!Config  Key  = SECHIBA_HISTLEVEL
!Config  Desc = SECHIBA history output level (0..10)
!Config  Def  = 5
!Config  Help = Chooses the list of variables in the history file. 
!Config         Values between 0: nothing is written; 10: everything is 
!Config         written are available More details can be found on the web under documentation.
!Config         web under documentation.
hist_level = 5
CALL getin_p('SECHIBA_HISTLEVEL', hist_level)
!- define operations as a function of history level.
!- Above hist_level, operation='never'
ave(1:max_hist_level) = 'ave(X)'
IF (hist_level < max_hist_level) THEN
       ave(hist_level+1:max_hist_level) = 'never'
ENDIF
sumscatter(1:max_hist_level) = 't_sum(scatter(X))'
IF (hist_level < max_hist_level) THEN
       sumscatter(hist_level+1:max_hist_level) = 'never'
ENDIF
avecels(1:max_hist_level) = 'ave(cels(X))'
IF (hist_level < max_hist_level) THEN
       avecels(hist_level+1:max_hist_level) = 'never'
ENDIF
avescatter(1:max_hist_level) = 'ave(scatter(X))'
IF (hist_level < max_hist_level) THEN
       avescatter(hist_level+1:max_hist_level) = 'never'
ENDIF
tmincels(1:max_hist_level) = 't_min(cels(X))'
IF (hist_level < max_hist_level) THEN
       tmincels(hist_level+1:max_hist_level) = 'never'
ENDIF
tmaxcels(1:max_hist_level) = 't_max(cels(X))'
IF (hist_level < max_hist_level) THEN
       tmaxcels(hist_level+1:max_hist_level) = 'never'
ENDIF
fluxop(1:max_hist_level) = flux_op
IF (hist_level < max_hist_level) THEN
       fluxop(hist_level+1:max_hist_level) = 'never'
ENDIF
fluxop_scinsec(1:max_hist_level) = flux_scinsec
IF (hist_level < max_hist_level) THEN
       fluxop_scinsec(hist_level+1:max_hist_level) = 'never'
ENDIF
once(1:max_hist_level) = 'once(scatter(X))'
IF (hist_level < max_hist_level) THEN
       once(hist_level+1:max_hist_level) = 'never'
ENDIF

If for example hist_lev=5, for a variable with a corresponding histdef call containing operator(6), operator(6) is ‘never’ and the variable won’t appear in the history file. For another variable with a corresponding histdef call containing operator(4), the variable will be processing according to the operator definition and written in the history file.

Example:

ALMA convention

Here we divide per dt to get per seconds:

CALL histdef(hist_id, 'Evap', 'Total Evapotranspiration', 'kg/m2/s', & 
           & iim,jjm, hori_id, 1,1,1, -99, 32, fluxop_scinsec(1), dt, dw) 

NOT ALMA

Here we multiply per one_day/dt to get per days:

CALL histdef(hist_id, 'evap', 'Evaporation', 'mm/d', & 
           & iim,jjm, hori_id, 1,1,1, -99, 32, fluxop(1), dt, dw) 
Last modified 11 months ago Last modified on 03/03/20 15:46:43