Index: palm/trunk/SOURCE/data_output_binary_module.f90
===================================================================
--- palm/trunk/SOURCE/data_output_binary_module.f90	(revision 4596)
+++ palm/trunk/SOURCE/data_output_binary_module.f90	(revision 4597)
@@ -24,4 +24,7 @@
 ! -----------------
 ! $Id$
+! change: update argument list of routine binary_init_dimension due to changes in interface
+!
+! 4579 2020-06-25 20:05:07Z gronemeier
 ! corrected formatting to follow PALM coding standard
 !
@@ -68,5 +71,4 @@
     INCLUDE "mpif.h"
 #endif
-
 
     CHARACTER(LEN=*), PARAMETER ::  config_file_name = 'BINARY_TO_NETCDF_CONFIG'  !< name of config file
@@ -88,11 +90,8 @@
     INTEGER ::  output_group_comm               !< MPI communicator addressing all MPI ranks which participate in output
 
-    INTEGER, DIMENSION(:), ALLOCATABLE ::  files_highest_variable_id  !< highest assigned ID of
-                                                                      !< variable or dimension in a file
-
-    LOGICAL ::  binary_open_file_first_call = .TRUE.  !< true if binary_open_file routine was not
-                                                      !< called yet
-    LOGICAL ::  config_file_open = .FALSE.            !< true if config file is opened and not
-                                                      !< closed
+    INTEGER, DIMENSION(:), ALLOCATABLE ::  files_highest_variable_id  !< highest assigned ID of variable or dimension in a file
+
+    LOGICAL ::  binary_open_file_first_call = .TRUE.  !< true if binary_open_file routine was not called yet
+    LOGICAL ::  config_file_open = .FALSE.            !< true if config file is opened and not closed
     LOGICAL ::  print_debug_output = .FALSE.          !< if true, debug output is printed
 
@@ -165,8 +164,6 @@
 
     INTEGER, INTENT(IN) ::  dom_global_id              !< global id within a file defined by DOM
-    INTEGER, INTENT(IN) ::  master_output_rank         !< MPI rank executing tasks which must be
-                                                       !< executed by a single PE
-    INTEGER, INTENT(IN) ::  mpi_comm_of_output_group   !< MPI communicator specifying the rank group
-                                                       !< participating in output
+    INTEGER, INTENT(IN) ::  master_output_rank         !< MPI rank executing tasks which must be executed by a single PE
+    INTEGER, INTENT(IN) ::  mpi_comm_of_output_group   !< MPI communicator specifying the rank group participating in output
     INTEGER, INTENT(IN) ::  program_debug_output_unit  !< file unit number for debug output
 
@@ -174,12 +171,12 @@
 
 
-    file_suffix       = file_suffix_of_output_group
-    output_group_comm = mpi_comm_of_output_group
-    master_rank       = master_output_rank
+    file_suffix        = file_suffix_of_output_group
+    output_group_comm  = mpi_comm_of_output_group
+    master_rank        = master_output_rank
 
     debug_output_unit  = program_debug_output_unit
     print_debug_output = debug_output
 
-    global_id_in_file = dom_global_id
+    global_id_in_file  = dom_global_id
 
  END SUBROUTINE binary_init_module
@@ -204,6 +201,5 @@
     INTEGER, INTENT(OUT) ::  return_value  !< return value
 
-    INTEGER, DIMENSION(:), ALLOCATABLE ::  files_highest_variable_id_tmp  !< temporary list of given
-                                                                          !< variable IDs in file
+    INTEGER, DIMENSION(:), ALLOCATABLE ::  files_highest_variable_id_tmp  !< temporary list of given variable IDs in file
 
     LOGICAL ::  file_exists  !< true if file to be opened already exists
@@ -238,12 +234,13 @@
 !
 !--       Remove any pre-existing file
-          INQUIRE( FILE=TRIM( config_file_name ) // TRIM( file_suffix ), EXIST = file_exists )
+          INQUIRE( FILE=TRIM( config_file_name ) // TRIM( file_suffix ), EXIST=file_exists )
 
           IF ( file_exists )  THEN
-             CALL internal_message( 'debug', routine_name // ': Remove existing file ' //          &
+             CALL internal_message( 'debug', routine_name //                                       &
+                                    ': Remove existing file ' //                                   &
                                     TRIM( config_file_name ) // TRIM( file_suffix ) )
              !> @note Fortran2008 feature 'EXECUTE_COMMAND_LINE' not yet supported by
              !>       PGI 18.10 compiler. Hence, non-standard 'SYSTEM' call must be used
-             ! CALL EXECUTE_COMMAND_LINE(                                                &
+             ! CALL EXECUTE_COMMAND_LINE( &
              !         COMMAND='rm ' // TRIM( config_file_name ) // TRIM( file_suffix ), &
              !         WAIT=.TRUE., EXITSTAT=return_value )
@@ -288,6 +285,6 @@
 
        IF ( file_exists )  THEN
-          CALL internal_message( 'debug', routine_name // ': remove existing file ' //             &
-                                 TRIM( bin_filename ) )
+          CALL internal_message( 'debug', routine_name //                                          &
+                                 ': remove existing file ' // TRIM( bin_filename ) )
           !> @note Fortran2008 feature 'EXECUTE_COMMAND_LINE' not yet supported by
           !>       PGI 18.10 compiler. Hence, non-standard 'SYSTEM' call must be used
@@ -320,5 +317,5 @@
 !--       Extend file-variable/dimension-ID list by 1 and set it to 0 for new file.
           IF ( ALLOCATED( files_highest_variable_id ) )  THEN
-             ALLOCATE( files_highest_variable_id_tmp( SIZE( files_highest_variable_id ) ) )
+             ALLOCATE( files_highest_variable_id_tmp(SIZE( files_highest_variable_id )) )
              files_highest_variable_id_tmp = files_highest_variable_id
              DEALLOCATE( files_highest_variable_id )
@@ -333,6 +330,6 @@
        ELSE
           return_value = 1
-          CALL internal_message( 'error', routine_name // ': could not open file "' //             &
-                                 TRIM( file_name ) // '"')
+          CALL internal_message( 'error', routine_name //                                          &
+                                 ': could not open file "' // TRIM( file_name ) // '"')
        ENDIF
 
@@ -349,5 +346,4 @@
                                     value_int16, value_int32, value_real32, value_real64,          &
                                     return_value )
-
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_write_attribute'  !< name of this routine
@@ -372,6 +368,6 @@
     return_value = 0
 
-    CALL internal_message( 'debug', TRIM( routine_name ) // ': write attribute ' //                &
-                           TRIM( attribute_name ) )
+    CALL internal_message( 'debug', TRIM( routine_name ) //                                        &
+                           ': write attribute ' // TRIM( attribute_name ) )
 !
 !-- Write attribute to file
@@ -418,8 +414,9 @@
 ! ------------
 !> Initialize dimension. Write information in file header and save dimension values to be later
-!< written to file.
+!> written to file.
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE binary_init_dimension( mode, file_id, dimension_id, variable_id, dimension_name,       &
-                                   dimension_type, dimension_length, return_value )
+                                   dimension_type, dimension_length, write_only_by_master_rank,    &
+                                   return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_init_dimension'  !< name of this routine
@@ -436,4 +433,6 @@
     INTEGER, INTENT(OUT) ::  variable_id       !< variable ID
 
+    LOGICAL, INTENT(IN) ::  write_only_by_master_rank  !< true if only master rank shall write variable
+
 
     return_value = 0
@@ -441,5 +440,5 @@
     CALL internal_message( 'debug', routine_name // ': init dimension ' // TRIM( dimension_name ) )
 !
-!-- Check mode (not required, added for compatibility reasons only)
+!-- Required for compatibility reasons
     IF ( TRIM( mode ) == mode_binary )  CONTINUE
 !
@@ -458,5 +457,8 @@
 !-- Define variable associated with dimension
     CALL binary_init_variable( mode, file_id, variable_id, dimension_name, dimension_type,         &
-                               (/ dimension_id /), is_global=.TRUE., return_value=return_value )
+                               (/ dimension_id /),                                                 &
+                               write_only_by_master_rank=write_only_by_master_rank,                &
+                               return_value=return_value )
+
     IF ( return_value /= 0 )  THEN
        CALL internal_message( 'error', routine_name //                                             &
@@ -472,10 +474,10 @@
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE binary_init_variable( mode, file_id, variable_id, variable_name, variable_type,        &
-                                  dimension_ids, is_global, return_value )
+                                  dimension_ids, write_only_by_master_rank, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_init_variable'  !< name of this routine
 
+    CHARACTER(LEN=*),       INTENT(IN) ::  mode            !< operation mode
     CHARACTER(LEN=charlen)             ::  output_string   !< output string
-    CHARACTER(LEN=*),       INTENT(IN) ::  mode            !< operation mode
     CHARACTER(LEN=charlen), INTENT(IN) ::  variable_name   !< name of variable
     CHARACTER(LEN=charlen), INTENT(IN) ::  variable_type   !< data type of variable
@@ -487,5 +489,5 @@
     INTEGER, DIMENSION(:), INTENT(IN) ::  dimension_ids  !< list of dimension IDs used by variable
 
-    LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global (same on all PE)
+    LOGICAL, INTENT(IN) ::  write_only_by_master_rank  !< true if only master rank shall write variable
 
 
@@ -494,9 +496,7 @@
     CALL internal_message( 'debug', routine_name // ': init variable ' // TRIM( variable_name ) )
 !
-!-- Check mode (not required, added for compatibility reasons only)
+!-- Required for compatibility reasons
     IF ( TRIM( mode ) == mode_binary )  CONTINUE
-!
-!-- Check if variable is global (not required, added for compatibility reasons only)
-    IF ( is_global )  CONTINUE
+    IF ( write_only_by_master_rank )  CONTINUE
 !
 !-- Assign variable ID
@@ -533,6 +533,6 @@
 
     WRITE( temp_string, * ) file_id
-    CALL internal_message( 'debug', routine_name // ': finalize file definition (file_id=' //      &
-                           TRIM( temp_string ) // ')' )
+    CALL internal_message( 'debug', routine_name //                                                &
+                           ': finalize file definition (file_id=' // TRIM( temp_string ) // ')' )
 
     output_string = '*** end file header ***'
@@ -547,16 +547,15 @@
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE binary_write_variable(                                                                 &
-                           file_id, variable_id, bounds_start, value_counts, bounds_origin,        &
-                           is_global,                                                              &
-                           values_char_0d,   values_char_1d,   values_char_2d,   values_char_3d,   &
-                           values_int8_0d,   values_int8_1d,   values_int8_2d,   values_int8_3d,   &
-                           values_int16_0d,  values_int16_1d,  values_int16_2d,  values_int16_3d,  &
-                           values_int32_0d,  values_int32_1d,  values_int32_2d,  values_int32_3d,  &
-                           values_intwp_0d,  values_intwp_1d,  values_intwp_2d,  values_intwp_3d,  &
-                           values_real32_0d, values_real32_1d, values_real32_2d, values_real32_3d, &
-                           values_real64_0d, values_real64_1d, values_real64_2d, values_real64_3d, &
-                           values_realwp_0d, values_realwp_1d, values_realwp_2d, values_realwp_3d, &
-                           return_value )
-
+               file_id, variable_id, bounds_start, value_counts, bounds_origin,                    &
+               write_only_by_master_rank,                                                          &
+               values_char_0d,   values_char_1d,   values_char_2d,   values_char_3d,               &
+               values_int8_0d,   values_int8_1d,   values_int8_2d,   values_int8_3d,               &
+               values_int16_0d,  values_int16_1d,  values_int16_2d,  values_int16_3d,              &
+               values_int32_0d,  values_int32_1d,  values_int32_2d,  values_int32_3d,              &
+               values_intwp_0d,  values_intwp_1d,  values_intwp_2d,  values_intwp_3d,              &
+               values_real32_0d, values_real32_1d, values_real32_2d, values_real32_3d,             &
+               values_real64_0d, values_real64_1d, values_real64_2d, values_real64_3d,             &
+               values_realwp_0d, values_realwp_1d, values_realwp_2d, values_realwp_3d,             &
+               return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_write_variable'  !< name of this routine
@@ -570,6 +569,6 @@
 
     INTEGER, INTENT(IN)  ::  file_id       !< file ID
+    INTEGER, INTENT(OUT) ::  return_value  !< return value
     INTEGER, INTENT(IN)  ::  variable_id   !< variable ID
-    INTEGER, INTENT(OUT) ::  return_value  !< return value
 
     INTEGER, DIMENSION(:), INTENT(IN) ::  bounds_origin  !< starting index of each dimension
@@ -594,5 +593,5 @@
     INTEGER(iwp),    POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  values_intwp_3d  !< output variable
 
-    LOGICAL, INTENT(IN) ::  is_global  !< true if variable is global (same on all PE)
+    LOGICAL, INTENT(IN) ::  write_only_by_master_rank  !< true if only master rank shall write variable
 
     REAL(KIND=4), POINTER,             INTENT(IN), OPTIONAL                   ::  values_real32_0d  !< output variable
@@ -614,6 +613,7 @@
     WRITE( temp_string, '(": write variable ",I6," into file ",I6)' ) variable_id, file_id
     CALL internal_message( 'debug', routine_name // TRIM( temp_string ) )
-
-    IF ( is_global )  CONTINUE  ! reqired to prevent compiler warning
+!
+!-- Required for compatibility reasons
+    IF ( write_only_by_master_rank )  CONTINUE
 
     IF ( .NOT. ANY( value_counts == 0 ) )  THEN
@@ -695,5 +695,5 @@
           WRITE( file_id )  values_int32_3d
 !
-!--    working-precision integer output
+!--    Working-precision integer output
        ELSEIF ( PRESENT( values_intwp_0d ) )  THEN
           output_string = 'intwp'
@@ -749,5 +749,5 @@
           WRITE( file_id )  values_real64_3d
 !
-!--    working-precision real output
+!--    Working-precision real output
        ELSEIF ( PRESENT( values_realwp_0d ) )  THEN
           output_string = 'realwp'
Index: palm/trunk/SOURCE/data_output_module.f90
===================================================================
--- palm/trunk/SOURCE/data_output_module.f90	(revision 4596)
+++ palm/trunk/SOURCE/data_output_module.f90	(revision 4597)
@@ -24,4 +24,9 @@
 ! -----------------
 ! $Id$
+! bugfix: - write unlimited dimension in netcdf4-parallel mode
+! new   : - added optional argument to dom_def_dim to allow that dimension variables can be written
+!           by every PE
+!
+! 4579 2020-06-25 20:05:07Z gronemeier
 ! corrected formatting to follow PALM coding standard
 !
@@ -116,21 +121,22 @@
 
     TYPE variable_type
-       CHARACTER(LEN=charlen)                            ::  data_type = ''       !< data type
-       CHARACTER(LEN=charlen)                            ::  name                 !< variable name
-       INTEGER                                           ::  id = no_id           !< id within file
-       LOGICAL                                           ::  is_global = .FALSE.  !< true if global variable
-       CHARACTER(LEN=charlen), DIMENSION(:), ALLOCATABLE ::  dimension_names      !< list of dimension names used by variable
-       INTEGER,                DIMENSION(:), ALLOCATABLE ::  dimension_ids        !< list of dimension ids used by variable
-       TYPE(attribute_type),   DIMENSION(:), ALLOCATABLE ::  attributes           !< list of attributes
+       CHARACTER(LEN=charlen) ::  data_type = ''                              !< data type
+       CHARACTER(LEN=charlen) ::  name                                        !< variable name
+       INTEGER                ::  id = no_id                                  !< id within file
+       LOGICAL                ::  write_only_by_master_rank = .FALSE.         !< true if only master rank shall write variable
+       CHARACTER(LEN=charlen), DIMENSION(:), ALLOCATABLE ::  dimension_names  !< list of dimension names used by variable
+       INTEGER,                DIMENSION(:), ALLOCATABLE ::  dimension_ids    !< list of dimension ids used by variable
+       TYPE(attribute_type),   DIMENSION(:), ALLOCATABLE ::  attributes       !< list of attributes
     END TYPE variable_type
 
     TYPE dimension_type
-       CHARACTER(LEN=charlen)                     ::  data_type = ''        !< data type
-       CHARACTER(LEN=charlen)                     ::  name                  !< dimension name
-       INTEGER                                    ::  id = no_id            !< dimension id within file
-       INTEGER                                    ::  length                !< length of dimension
-       INTEGER                                    ::  length_mask           !< length of masked dimension
-       INTEGER                                    ::  variable_id = no_id   !< associated variable id within file
-       LOGICAL                                    ::  is_masked = .FALSE.   !< true if masked
+       CHARACTER(LEN=charlen) ::  data_type = ''                            !< data type
+       CHARACTER(LEN=charlen) ::  name                                      !< dimension name
+       INTEGER                ::  id = no_id                                !< dimension id within file
+       INTEGER                ::  length                                    !< length of dimension
+       INTEGER                ::  length_mask                               !< length of masked dimension
+       INTEGER                ::  variable_id = no_id                       !< associated variable id within file
+       LOGICAL                ::  is_masked = .FALSE.                       !< true if masked
+       LOGICAL                ::  write_only_by_master_rank = .FALSE.       !< true if only master rank shall write variable
        INTEGER,         DIMENSION(2)              ::  bounds                !< lower and upper bound of dimension
        INTEGER,         DIMENSION(:), ALLOCATABLE ::  masked_indices        !< list of masked indices of dimension
@@ -365,4 +371,6 @@
 !> given which is then used to fill the entire dimension.
 !> An optional mask can be given to mask limited dimensions.
+!> Per default, a dimension is written to file only by the output master rank. However, this
+!> behaviour can be changed via the optional parameter 'write_only_by_master_rank'.
 !> Example call:
 !>   - fixed dimension with 100 entries (values known):
@@ -382,5 +390,15 @@
 !>                             output_type='real32', bounds=(/1/), &
 !>                             values_real32=(/fill_value/) )
+!>   - dimension values must be written by all MPI ranks later
+!>     (e.g. the master output rank does not know all dimension values):
+!>       status = dom_def_dim( file_name='my_output_file_name', dimension_name='my_dimension', &
+!>                             output_type='real32', bounds=(/1,100/), &
+!>                             values_real32=(/fill_value/), write_only_by_master_rank = .FALSE. )
 !>
+!> @note The optional argument 'write_only_by_master_rank' is set true by default to reduce the
+!>       number of file accesses. If dimension values must, however, be written by all MPI ranks
+!>       (e.g. each rank only knows parts of the values), 'write_only_by_master_rank' must be set
+!>       false to allow each rank to write values to the file for this dimension.
+!>       Values must be written after definition stage via calling dom_write_var.
 !> @todo Convert given values into selected output_type.
 !--------------------------------------------------------------------------------------------------!
@@ -388,5 +406,5 @@
                        values_int8, values_int16, values_int32, values_intwp,                      &
                        values_real32, values_real64, values_realwp,                                &
-                       mask )                                                                      &
+                       mask, write_only_by_master_rank )                                           &
              RESULT( return_value )
 
@@ -401,18 +419,20 @@
     INTEGER ::  i             !< loop index
     INTEGER ::  j             !< loop index
-    INTEGER ::  ndims = 0     !< number of dimensions in file
+    INTEGER ::  ndims         !< number of dimensions in file
     INTEGER ::  return_value  !< return value
 
-    INTEGER,         DIMENSION(:), INTENT(IN)           ::  bounds         !< lower and upper bound of dimension variable
-    INTEGER(KIND=1), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_int8    !< values of dimension
-    INTEGER(KIND=2), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_int16   !< values of dimension
-    INTEGER(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_int32   !< values of dimension
-    INTEGER(iwp),    DIMENSION(:), INTENT(IN), OPTIONAL ::  values_intwp   !< values of dimension
-
-    LOGICAL,         DIMENSION(:), INTENT(IN), OPTIONAL ::  mask           !< mask of dimesion
-
-    REAL(KIND=4),    DIMENSION(:), INTENT(IN), OPTIONAL ::  values_real32  !< values of dimension
-    REAL(KIND=8),    DIMENSION(:), INTENT(IN), OPTIONAL ::  values_real64  !< values of dimension
-    REAL(wp),        DIMENSION(:), INTENT(IN), OPTIONAL ::  values_realwp  !< values of dimension
+    INTEGER,         DIMENSION(:), INTENT(IN)           ::  bounds        !< lower and upper bound of dimension variable
+    INTEGER(KIND=1), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_int8   !< values of dimension
+    INTEGER(KIND=2), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_int16  !< values of dimension
+    INTEGER(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_int32  !< values of dimension
+    INTEGER(iwp),    DIMENSION(:), INTENT(IN), OPTIONAL ::  values_intwp  !< values of dimension
+
+    LOGICAL, INTENT(IN), OPTIONAL ::  write_only_by_master_rank  !< true if only master rank shall write this variable
+
+    LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL ::  mask  !< mask of dimesion
+
+    REAL(KIND=4), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_real32  !< values of dimension
+    REAL(KIND=8), DIMENSION(:), INTENT(IN), OPTIONAL ::  values_real64  !< values of dimension
+    REAL(wp),     DIMENSION(:), INTENT(IN), OPTIONAL ::  values_realwp  !< values of dimension
 
     TYPE(dimension_type)                            ::  dimension       !< new dimension
@@ -421,4 +441,5 @@
 
     return_value = 0
+    ndims = 0
 
     CALL internal_message( 'debug', routine_name //                                                &
@@ -429,4 +450,10 @@
     dimension%name      = TRIM( dimension_name )
     dimension%data_type = TRIM( output_type )
+
+    IF ( PRESENT( write_only_by_master_rank ) )  THEN
+       dimension%write_only_by_master_rank = write_only_by_master_rank
+    ELSE
+       dimension%write_only_by_master_rank = .TRUE.
+    ENDIF
 !
 !-- Check dimension bounds and allocate dimension according to bounds
@@ -692,8 +719,8 @@
                          return_value = 1
                          CALL internal_message( 'error', routine_name //                           &
-                                        ': file already has a variable of this name defined. ' //  &
-                                        'Defining a dimension of the same name is not allowed ' // &
-                                        '(dimension "' // TRIM( dimension_name ) //                &
-                                       '", file "' // TRIM( file_name ) // '")!' )
+                                 ': file already has a variable of this name defined. ' //         &
+                                 'Defining a dimension of the same name is not allowed ' //        &
+                                 '(dimension "' // TRIM( dimension_name ) //                       &
+                                 '", file "' // TRIM( file_name ) // '")!' )
                          EXIT
                       ENDIF
@@ -754,7 +781,4 @@
 ! ------------
 !> Add variable to database.
-!> If a variable is identical for each MPI rank, the optional argument 'is_global' should be set to
-!> .TRUE. This flags the variable to be a global variable and is later only written once by the
-!> master output rank.
 !> Example call:
 !>   dom_def_var( file_name =  'my_output_file_name', &
@@ -774,6 +798,14 @@
 !>       or
 !>          ALLOCATE( u(<z>,<y>,<x>) )
-!--------------------------------------------------------------------------------------------------!
- FUNCTION dom_def_var( file_name, variable_name, dimension_names, output_type, is_global )         &
+!> @note The optional argument 'write_only_by_master_rank' can be used to reduce the number of file
+!>       accesses. If a variable is identical on each MPI rank, setting 'write_only_by_master_rank'
+!>       allows the underlying output modules to skip the write command if possible for MPI ranks
+!>       other than the master output rank.
+!>       As restrictions may apply for different output modules, it might be possible that this
+!>       option is ignored internally. Hence, all MPI ranks must still participate in the
+!>       dom_write_var calls in any case.
+!--------------------------------------------------------------------------------------------------!
+ FUNCTION dom_def_var( file_name, variable_name, dimension_names, output_type,                     &
+                       write_only_by_master_rank )                                                 &
              RESULT( return_value )
 
@@ -792,6 +824,6 @@
     INTEGER ::  return_value  !< return value
 
-    LOGICAL                       ::  found      !< true if requested dimension is defined in file
-    LOGICAL, INTENT(IN), OPTIONAL ::  is_global  !< true if variable is global (same on all PE)
+    LOGICAL                       ::  found                      !< true if requested dimension is defined in file
+    LOGICAL, INTENT(IN), OPTIONAL ::  write_only_by_master_rank  !< true if only master rank shall write this variable
 
     TYPE(variable_type)                            ::  variable       !< new variable
@@ -815,8 +847,8 @@
     variable%data_type = TRIM( output_type )
 
-    IF ( PRESENT( is_global ) )  THEN
-       variable%is_global = is_global
+    IF ( PRESENT( write_only_by_master_rank ) )  THEN
+       variable%write_only_by_master_rank = write_only_by_master_rank
     ELSE
-       variable%is_global = .FALSE.
+       variable%write_only_by_master_rank = .FALSE.
     ENDIF
 !
@@ -830,7 +862,7 @@
              return_value = 1
              CALL internal_message( 'error', routine_name //                                       &
-                          ': file already initialized. No further variable definition allowed ' // &
-                          '(variable "' // TRIM( variable_name ) //                                &
-                          '", file "' // TRIM( file_name ) // '")!' )
+                     ': file already initialized. No further variable definition allowed ' //      &
+                     '(variable "' // TRIM( variable_name ) //                                     &
+                     '", file "' // TRIM( file_name ) // '")!' )
              EXIT
 
@@ -842,8 +874,8 @@
                    return_value = 1
                    CALL internal_message( 'error', routine_name //                                 &
-                                        ': file already has a dimension of this name defined. ' // &
-                                        'Defining a variable of the same name is not allowed ' //  &
-                                        '(variable "' // TRIM( variable_name ) //                  &
-                                        '", file "' // TRIM( file_name ) // '")!' )
+                           ': file already has a dimension of this name defined. ' //              &
+                           'Defining a variable of the same name is not allowed ' //               &
+                           '(variable "' // TRIM( variable_name ) //                               &
+                           '", file "' // TRIM( file_name ) // '")!' )
                    EXIT
                 ENDIF
@@ -863,8 +895,8 @@
                       return_value = 1
                       CALL internal_message( 'error', routine_name //                              &
-                                 ': required dimension "'// TRIM( variable%dimension_names(i) ) // &
-                                 '" for variable is not defined ' //                               &
-                                 '(variable "' // TRIM( variable_name ) //                         &
-                                 '", file "' // TRIM( file_name ) // '")!' )
+                              ': required dimension "'//  TRIM( variable%dimension_names(i) ) //   &
+                              '" for variable is not defined ' //                                  &
+                              '(variable "' // TRIM( variable_name ) //                            &
+                              '", file "' // TRIM( file_name ) // '")!' )
                       EXIT
                    ENDIF
@@ -976,6 +1008,6 @@
     INTEGER ::  return_value  !< return value
 
+    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
     LOGICAL                       ::  append_internal  !< same as 'append'
-    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
 
     TYPE(attribute_type) ::  attribute  !< new attribute
@@ -1039,6 +1071,6 @@
     INTEGER ::  return_value  !< return value
 
+    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
     LOGICAL                       ::  append_internal  !< same as 'append'
-    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
 
     TYPE(attribute_type) ::  attribute  !< new attribute
@@ -1111,6 +1143,6 @@
     INTEGER ::  return_value  !< return value
 
+    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
     LOGICAL                       ::  append_internal  !< same as 'append'
-    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
 
     TYPE(attribute_type) ::  attribute  !< new attribute
@@ -1174,5 +1206,4 @@
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'dom_def_att_int32'  !< name of routine
 
-
     CHARACTER(LEN=*),      INTENT(IN)           ::  attribute_name          !< name of attribute
     CHARACTER(LEN=*),      INTENT(IN)           ::  file_name               !< name of file
@@ -1184,6 +1215,6 @@
     INTEGER ::  return_value  !< return value
 
+    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
     LOGICAL                       ::  append_internal  !< same as 'append'
-    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
 
     TYPE(attribute_type) ::  attribute  !< new attribute
@@ -1254,6 +1285,6 @@
     INTEGER ::  return_value  !< return value
 
+    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
     LOGICAL                       ::  append_internal  !< same as 'append'
-    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
 
     REAL(KIND=4), INTENT(IN) ::  value  !< attribute value
@@ -1326,6 +1357,6 @@
     INTEGER ::  return_value  !< return value
 
+    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
     LOGICAL                       ::  append_internal  !< same as 'append'
-    LOGICAL, INTENT(IN), OPTIONAL ::  append           !< if true, append value to existing value
 
     REAL(KIND=8), INTENT(IN) ::  value  !< attribute value
@@ -1584,5 +1615,4 @@
     INTEGER, DIMENSION(:),   INTENT(IN)  ::  bounds_end             !< end index per dimension of variable
     INTEGER, DIMENSION(:),   INTENT(IN)  ::  bounds_start           !< start index per dimension of variable
-
     INTEGER, DIMENSION(:),   ALLOCATABLE ::  bounds_origin          !< first index of each dimension
     INTEGER, DIMENSION(:),   ALLOCATABLE ::  bounds_start_internal  !< start index per dim. for output after masking
@@ -1590,6 +1620,6 @@
     INTEGER, DIMENSION(:,:), ALLOCATABLE ::  masked_indices         !< list containing all output indices along a dimension
 
-    LOGICAL ::  do_output  !< true if any data lies within given range of masked dimension
-    LOGICAL ::  is_global  !< true if variable is global
+    LOGICAL ::  do_output                  !< true if any data lies within given range of masked dimension
+    LOGICAL ::  write_only_by_master_rank  !< true if only master rank shall write variable
 
     INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL                   ::  values_int8_0d             !< output variable
@@ -1687,5 +1717,5 @@
 !-- Search for variable within file
     CALL find_var_in_file( file_name, variable_name, file_format, file_id, variable_id,            &
-                           is_global, dimension_list, return_value=return_value  )
+                           write_only_by_master_rank, dimension_list, return_value=return_value  )
 
     IF ( return_value == 0 )  THEN
@@ -1740,5 +1770,5 @@
 !
 !--    Mask and resort variable
-!--    character output
+!--    Character output
        IF ( PRESENT( values_char_0d ) )  THEN
           values_char_0d_pointer => values_char_0d
@@ -1845,5 +1875,5 @@
                       values_int8_3d_resorted(i,j,k) = values_int8_3d(masked_indices(3,k),         &
                                                                       masked_indices(2,j),         &
-                                                                      masked_indices(1,i)  )
+                                                                      masked_indices(1,i))
                    ENDDO
                 ENDDO
@@ -2225,145 +2255,177 @@
 !--          Character output
              IF ( PRESENT( values_char_0d ) )  THEN
-                 CALL binary_write_variable( file_id, variable_id,                                 &
-                         bounds_start_internal, value_counts, bounds_origin, is_global,            &
-                        values_char_0d=values_char_0d_pointer, return_value=output_return_value )
+                CALL binary_write_variable( file_id, variable_id,                                  &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_0d=values_char_0d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_char_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_char_1d=values_char_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_1d=values_char_1d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_char_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_char_2d=values_char_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_2d=values_char_2d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_char_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_char_3d=values_char_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_3d=values_char_3d_pointer,          &
+                        return_value=output_return_value )
 !
 !--          8bit integer output
              ELSEIF ( PRESENT( values_int8_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_0d=values_int8_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_0d=values_int8_0d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int8_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_1d=values_int8_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_1d=values_int8_1d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int8_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_2d=values_int8_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_2d=values_int8_2d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int8_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_3d=values_int8_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_3d=values_int8_3d_pointer,          &
+                        return_value=output_return_value )
 !
 !--          16bit integer output
              ELSEIF ( PRESENT( values_int16_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_0d=values_int16_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_0d=values_int16_0d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int16_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_1d=values_int16_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_1d=values_int16_1d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int16_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_2d=values_int16_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_2d=values_int16_2d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int16_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_3d=values_int16_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_3d=values_int16_3d_pointer,        &
+                        return_value=output_return_value )
 !
 !--          32bit integer output
              ELSEIF ( PRESENT( values_int32_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_0d=values_int32_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_0d=values_int32_0d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int32_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_1d=values_int32_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_1d=values_int32_1d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int32_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_2d=values_int32_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_2d=values_int32_2d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int32_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_3d=values_int32_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_3d=values_int32_3d_pointer,        &
+                        return_value=output_return_value )
 !
 !--          Working-precision integer output
              ELSEIF ( PRESENT( values_intwp_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_0d=values_intwp_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_0d=values_intwp_0d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_intwp_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_1d=values_intwp_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_1d=values_intwp_1d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_intwp_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_2d=values_intwp_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_2d=values_intwp_2d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_intwp_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_3d=values_intwp_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_3d=values_intwp_3d_pointer,        &
+                        return_value=output_return_value )
 !
 !--          32bit real output
              ELSEIF ( PRESENT( values_real32_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_0d=values_real32_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_0d=values_real32_0d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real32_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_1d=values_real32_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_1d=values_real32_1d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real32_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_2d=values_real32_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_2d=values_real32_2d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real32_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_3d=values_real32_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_3d=values_real32_3d_pointer,      &
+                        return_value=output_return_value )
 !
 !--          64bit real output
              ELSEIF ( PRESENT( values_real64_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_0d=values_real64_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_0d=values_real64_0d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real64_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_1d=values_real64_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_1d=values_real64_1d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real64_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_2d=values_real64_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_2d=values_real64_2d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real64_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_3d=values_real64_3d_pointer, return_value=output_return_value )
-!
-!--          working-precision real output
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_3d=values_real64_3d_pointer,      &
+                        return_value=output_return_value )
+!
+!--          Working-precision real output
              ELSEIF ( PRESENT( values_realwp_0d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_0d=values_realwp_0d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_0d=values_realwp_0d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_realwp_1d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_1d=values_realwp_1d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_1d=values_realwp_1d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_realwp_2d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_2d=values_realwp_2d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_2d=values_realwp_2d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_realwp_3d ) )  THEN
                 CALL binary_write_variable( file_id, variable_id,                                  &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_3d=values_realwp_3d_pointer, return_value=output_return_value )
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_3d=values_realwp_3d_pointer,      &
+                        return_value=output_return_value )
              ELSE
                 return_value = 1
@@ -2377,147 +2439,179 @@
           CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
 !
-!--          Character output
+!--          Character integer output
              IF ( PRESENT( values_char_0d ) )  THEN
-                 CALL netcdf4_write_variable( file_id, variable_id,                                &
-                         bounds_start_internal, value_counts, bounds_origin, is_global,            &
-                        values_char_0d=values_char_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_0d=values_char_0d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_char_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_char_1d=values_char_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_1d=values_char_1d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_char_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_char_2d=values_char_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_2d=values_char_2d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_char_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_char_3d=values_char_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_char_3d=values_char_3d_pointer,          &
+                        return_value=output_return_value )
 !
 !--          8bit integer output
              ELSEIF ( PRESENT( values_int8_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_0d=values_int8_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_0d=values_int8_0d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int8_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_1d=values_int8_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_1d=values_int8_1d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int8_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_2d=values_int8_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_2d=values_int8_2d_pointer,          &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int8_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int8_3d=values_int8_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int8_3d=values_int8_3d_pointer,          &
+                        return_value=output_return_value )
 !
 !--          16bit integer output
              ELSEIF ( PRESENT( values_int16_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_0d=values_int16_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_0d=values_int16_0d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int16_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_1d=values_int16_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_1d=values_int16_1d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int16_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_2d=values_int16_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_2d=values_int16_2d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int16_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int16_3d=values_int16_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int16_3d=values_int16_3d_pointer,        &
+                        return_value=output_return_value )
 !
 !--          32bit integer output
              ELSEIF ( PRESENT( values_int32_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_0d=values_int32_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_0d=values_int32_0d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int32_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_1d=values_int32_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_1d=values_int32_1d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int32_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_2d=values_int32_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_2d=values_int32_2d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_int32_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_int32_3d=values_int32_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_int32_3d=values_int32_3d_pointer,        &
+                        return_value=output_return_value )
 !
 !--          Working-precision integer output
              ELSEIF ( PRESENT( values_intwp_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_0d=values_intwp_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_0d=values_intwp_0d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_intwp_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_1d=values_intwp_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_1d=values_intwp_1d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_intwp_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_2d=values_intwp_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_2d=values_intwp_2d_pointer,        &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_intwp_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_intwp_3d=values_intwp_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_intwp_3d=values_intwp_3d_pointer,        &
+                        return_value=output_return_value )
 !
 !--          32bit real output
              ELSEIF ( PRESENT( values_real32_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_0d=values_real32_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_0d=values_real32_0d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real32_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_1d=values_real32_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_1d=values_real32_1d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real32_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_2d=values_real32_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_2d=values_real32_2d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real32_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real32_3d=values_real32_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real32_3d=values_real32_3d_pointer,      &
+                        return_value=output_return_value )
 !
 !--          64bit real output
              ELSEIF ( PRESENT( values_real64_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_0d=values_real64_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_0d=values_real64_0d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real64_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_1d=values_real64_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_1d=values_real64_1d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real64_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_2d=values_real64_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_2d=values_real64_2d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_real64_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_real64_3d=values_real64_3d_pointer, return_value=output_return_value )
-!
-!--          working-precision real output
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_real64_3d=values_real64_3d_pointer,      &
+                        return_value=output_return_value )
+!
+!--          Working-precision real output
              ELSEIF ( PRESENT( values_realwp_0d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_0d=values_realwp_0d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_0d=values_realwp_0d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_realwp_1d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_1d=values_realwp_1d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_1d=values_realwp_1d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_realwp_2d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_2d=values_realwp_2d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_2d=values_realwp_2d_pointer,      &
+                        return_value=output_return_value )
              ELSEIF ( PRESENT( values_realwp_3d ) )  THEN
-                CALL netcdf4_write_variable( file_id, variable_id,                                 &
-                        bounds_start_internal, value_counts, bounds_origin, is_global,             &
-                        values_realwp_3d=values_realwp_3d_pointer, return_value=output_return_value )
+                CALL netcdf4_write_variable( TRIM( file_format(9:) ), file_id, variable_id,        &
+                        bounds_start_internal, value_counts, bounds_origin,                        &
+                        write_only_by_master_rank, values_realwp_3d=values_realwp_3d_pointer,      &
+                        return_value=output_return_value )
              ELSE
                 return_value = 1
@@ -2585,5 +2679,6 @@
 
              CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
-                CALL netcdf4_finalize( files(f)%id, output_return_value )
+                CALL netcdf4_finalize( TRIM( files(f)%format(9:) ), files(f)%id,                   &
+                                       output_return_value )
 
              CASE DEFAULT
@@ -2853,8 +2948,8 @@
                 return_value = 1
                 CALL internal_message( 'error',                                                    &
-                                    routine_name //                                                &
-                                    ': requested dimension/variable "' // TRIM( variable_name ) // &
-                                    '" for attribute "' // TRIM( attribute%name ) //               &
-                                    '" does not exist in file "' // TRIM( file_name ) // '"' )
+                        routine_name //                                                            &
+                        ': requested dimension/variable "' // TRIM( variable_name ) //             &
+                        '" for attribute "' // TRIM( attribute%name ) //                           &
+                        '" does not exist in file "' // TRIM( file_name ) // '"' )
              ENDIF
 
@@ -2948,5 +3043,5 @@
           DO  i = 1, nvars
              dimension_is_used(d) =                                                                &
-                         ANY( files(f)%dimensions(d)%name == files(f)%variables(i)%dimension_names )
+                ANY( files(f)%dimensions(d)%name == files(f)%variables(i)%dimension_names )
              IF ( dimension_is_used(d) )  EXIT
           ENDDO
@@ -3064,5 +3159,6 @@
                                        file%dimensions(d)%id, file%dimensions(d)%name,             &
                                        file%dimensions(d)%data_type, file%dimensions(d)%length,    &
-                                       file%dimensions(d)%variable_id, return_value )
+                                       file%dimensions(d)%variable_id,                             &
+                                       file%dimensions(d)%write_only_by_master_rank, return_value )
 
           ELSE
@@ -3070,7 +3166,8 @@
 !--          Initialize masked dimension
              CALL init_file_dimension( file%format, file%id, file%name,                            &
-                                     file%dimensions(d)%id, file%dimensions(d)%name,               &
-                                     file%dimensions(d)%data_type, file%dimensions(d)%length_mask, &
-                                     file%dimensions(d)%variable_id, return_value )
+                     file%dimensions(d)%id, file%dimensions(d)%name,                               &
+                     file%dimensions(d)%data_type, file%dimensions(d)%length_mask,                 &
+                     file%dimensions(d)%variable_id,                                               &
+                     file%dimensions(d)%write_only_by_master_rank, return_value )
 
           ENDIF
@@ -3104,5 +3201,5 @@
                      file%variables(d)%id, file%variables(d)%name, file%variables(d)%data_type,    &
                      file%variables(d)%dimension_ids,                                              &
-                     file%variables(d)%is_global, return_value )
+                     file%variables(d)%write_only_by_master_rank, return_value )
 
              IF ( return_value == 0  .AND.  ALLOCATED( file%variables(d)%attributes ) )  THEN
@@ -3134,5 +3231,5 @@
  SUBROUTINE init_file_dimension( file_format, file_id, file_name,                                  &
                                  dimension_id, dimension_name, dimension_type, dimension_length,   &
-                                 variable_id, return_value )
+                                 variable_id, write_only_by_master_rank, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'init_file_dimension'  !< file format chosen for file
@@ -3150,4 +3247,6 @@
     INTEGER, INTENT(OUT) ::  variable_id          !< associated variable ID
 
+    LOGICAL, INTENT(IN)  ::  write_only_by_master_rank  !< true if only master rank shall write variable
+
 
     return_value = 0
@@ -3161,16 +3260,16 @@
        CASE ( 'binary' )
           CALL binary_init_dimension( 'binary', file_id, dimension_id, variable_id,                &
-                                       dimension_name, dimension_type, dimension_length,           &
-                                       return_value=output_return_value )
+                  dimension_name, dimension_type, dimension_length, write_only_by_master_rank,     &
+                  return_value=output_return_value )
 
        CASE ( 'netcdf4-serial' )
           CALL netcdf4_init_dimension( 'serial', file_id, dimension_id, variable_id,               &
-                                       dimension_name, dimension_type, dimension_length,           &
-                                       return_value=output_return_value )
+                  dimension_name, dimension_type, dimension_length, write_only_by_master_rank,     &
+                  return_value=output_return_value )
 
        CASE ( 'netcdf4-parallel' )
           CALL netcdf4_init_dimension( 'parallel', file_id, dimension_id, variable_id,             &
-                                       dimension_name, dimension_type, dimension_length,           &
-                                       return_value=output_return_value )
+                  dimension_name, dimension_type, dimension_length, write_only_by_master_rank,     &
+                  return_value=output_return_value )
 
        CASE DEFAULT
@@ -3197,5 +3296,5 @@
  SUBROUTINE init_file_variable( file_format, file_id, file_name,                                   &
                                 variable_id, variable_name, variable_type, dimension_ids,          &
-                                is_global, return_value )
+                                write_only_by_master_rank, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'init_file_variable'  !< file format chosen for file
@@ -3213,5 +3312,5 @@
     INTEGER, DIMENSION(:), INTENT(IN) ::  dimension_ids  !< list of dimension IDs used by variable
 
-    LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global
+    LOGICAL, INTENT(IN)  ::  write_only_by_master_rank  !< true if only master rank shall write variable
 
 
@@ -3226,13 +3325,16 @@
        CASE ( 'binary' )
           CALL binary_init_variable( 'binary', file_id, variable_id, variable_name,                &
-                  variable_type, dimension_ids, is_global, return_value=output_return_value )
+                  variable_type, dimension_ids, write_only_by_master_rank,                         &
+                  return_value=output_return_value )
 
        CASE ( 'netcdf4-serial' )
           CALL netcdf4_init_variable( 'serial', file_id, variable_id, variable_name,               &
-                  variable_type, dimension_ids, is_global, return_value=output_return_value )
+                  variable_type, dimension_ids, write_only_by_master_rank,                         &
+                  return_value=output_return_value )
 
        CASE ( 'netcdf4-parallel' )
           CALL netcdf4_init_variable( 'parallel', file_id, variable_id, variable_name,             &
-                  variable_type, dimension_ids, is_global, return_value=output_return_value )
+                  variable_type, dimension_ids, write_only_by_master_rank,                         &
+                  return_value=output_return_value )
 
        CASE DEFAULT
@@ -3268,6 +3370,6 @@
 
     INTEGER, INTENT(IN) ::  file_id              !< file ID
+    INTEGER             ::  return_value         !< return value
     INTEGER             ::  output_return_value  !< return value of a called output routine
-    INTEGER             ::  return_value         !< return value
     INTEGER, INTENT(IN) ::  variable_id          !< variable ID
 
@@ -3335,32 +3437,32 @@
 
              CASE( 'char' )
-                CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id,            &
-                        attribute_name=attribute%name, value_char=attribute%value_char,            &
-                        return_value=output_return_value )
+                CALL netcdf4_write_attribute( mode=file_format(9:), file_id=file_id,               &
+                        variable_id=variable_id, attribute_name=attribute%name,                    &
+                        value_char=attribute%value_char, return_value=output_return_value )
 
              CASE( 'int8' )
-                CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id,            &
-                        attribute_name=attribute%name, value_int8=attribute%value_int8,            &
-                        return_value=output_return_value )
+                CALL netcdf4_write_attribute( mode=file_format(9:), file_id=file_id,               &
+                        variable_id=variable_id, attribute_name=attribute%name,                    &
+                        value_int8=attribute%value_int8, return_value=output_return_value )
 
              CASE( 'int16' )
-                CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id,            &
-                        attribute_name=attribute%name, value_int16=attribute%value_int16,          &
-                        return_value=output_return_value )
+                CALL netcdf4_write_attribute( mode=file_format(9:), file_id=file_id,               &
+                        variable_id=variable_id, attribute_name=attribute%name,                    &
+                        value_int16=attribute%value_int16, return_value=output_return_value )
 
              CASE( 'int32' )
-                CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id,            &
-                        attribute_name=attribute%name, value_int32=attribute%value_int32,          &
-                        return_value=output_return_value )
+                CALL netcdf4_write_attribute( mode=file_format(9:), file_id=file_id,               &
+                        variable_id=variable_id, attribute_name=attribute%name,                    &
+                        value_int32=attribute%value_int32, return_value=output_return_value )
 
              CASE( 'real32' )
-                CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id,            &
-                        attribute_name=attribute%name, value_real32=attribute%value_real32,        &
-                        return_value=output_return_value )
+                CALL netcdf4_write_attribute( mode=file_format(9:), file_id=file_id,               &
+                        variable_id=variable_id, attribute_name=attribute%name,                    &
+                        value_real32=attribute%value_real32, return_value=output_return_value )
 
              CASE( 'real64' )
-                CALL netcdf4_write_attribute( file_id=file_id, variable_id=variable_id,            &
-                        attribute_name=attribute%name, value_real64=attribute%value_real64,        &
-                        return_value=output_return_value )
+                CALL netcdf4_write_attribute( mode=file_format(9:), file_id=file_id,               &
+                        variable_id=variable_id, attribute_name=attribute%name,                    &
+                        value_real64=attribute%value_real64, return_value=output_return_value )
 
              CASE DEFAULT
@@ -3408,5 +3510,5 @@
     INTEGER, INTENT(OUT) ::  return_value  !< return value
 
-    LOGICAL ::  found = .FALSE.  !< true if dimension required by variable was found in dimension list
+    LOGICAL ::  found  !< true if dimension required by variable was found in dimension list
 
     TYPE(dimension_type), DIMENSION(:), INTENT(IN) ::  dimensions  !< list of dimensions in file
@@ -3415,5 +3517,6 @@
 
 
-    return_value  = 0
+    return_value = 0
+    found = .FALSE.
     ndims = SIZE( dimensions )
     nvars = SIZE( variables )
@@ -3473,5 +3576,5 @@
 
        CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
-          CALL netcdf4_stop_file_header_definition( file_id, output_return_value )
+          CALL netcdf4_stop_file_header_definition( file_format(9:), file_id, output_return_value )
 
        CASE DEFAULT
@@ -3500,5 +3603,5 @@
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE find_var_in_file( file_name, variable_name, file_format, file_id, variable_id,         &
-                              is_global, dimensions, return_value )
+                              write_only_by_master_rank, dimensions, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'find_var_in_file'  !< name of routine
@@ -3517,6 +3620,6 @@
     INTEGER, DIMENSION(:), ALLOCATABLE ::  dimension_ids  !< list of dimension IDs used by variable
 
-    LOGICAL              ::  found      !< true if requested variable found in requested file
-    LOGICAL, INTENT(OUT) ::  is_global  !< true if variable is global
+    LOGICAL              ::  found                      !< true if requested variable found in requested file
+    LOGICAL, INTENT(OUT) ::  write_only_by_master_rank  !< true if only master rank shall write variable
 
     TYPE(dimension_type), DIMENSION(:), ALLOCATABLE, INTENT(OUT) ::  dimensions  !< list of dimensions used by variable
@@ -3546,6 +3649,6 @@
              IF ( TRIM( variable_name ) == TRIM( files(f)%variables(d)%name ) )  THEN
 
-                variable_id    = files(f)%variables(d)%id
-                is_global = files(f)%variables(d)%is_global
+                variable_id = files(f)%variables(d)%id
+                write_only_by_master_rank = files(f)%variables(d)%write_only_by_master_rank
 
                 ALLOCATE( dimension_ids(SIZE( files(f)%variables(d)%dimension_ids )) )
@@ -3578,6 +3681,6 @@
                 IF ( TRIM( variable_name ) == TRIM( files(f)%dimensions(d)%name ) )  THEN
 
-                   variable_id    = files(f)%dimensions(d)%variable_id
-                   is_global = .TRUE.
+                   variable_id = files(f)%dimensions(d)%variable_id
+                   write_only_by_master_rank = files(f)%dimensions(d)%write_only_by_master_rank
 
                    ALLOCATE( dimensions(1) )
@@ -3741,5 +3844,5 @@
 
     INTEGER, PARAMETER ::  indent_depth = 3        !< space per indentation
-    INTEGER, PARAMETER ::  max_keyname_length = 6  !< length of longest key name
+    INTEGER, PARAMETER ::  max_keyname_length = 8  !< length of longest key name
 
     CHARACTER(LEN=50) ::  write_format1  !< format for write statements
@@ -3805,5 +3908,5 @@
     SUBROUTINE print_attributes( indent_level, attributes )
 
-       INTEGER, PARAMETER  ::  max_keyname_length = 6  !< length of longest key name
+       INTEGER, PARAMETER ::  max_keyname_length = 6  !< length of longest key name
 
        CHARACTER(LEN=50) ::  write_format1  !< format for write statements
@@ -3865,5 +3968,5 @@
     SUBROUTINE print_dimensions( indent_level, dimensions )
 
-       INTEGER, PARAMETER  ::  max_keyname_length = 15  !< length of longest key name
+       INTEGER, PARAMETER ::  max_keyname_length = 26  !< length of longest key name
 
        CHARACTER(LEN=50) ::  write_format1  !< format for write statements
@@ -3900,4 +4003,6 @@
           WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)' )                              &
              'id', dimensions(i)%id
+          WRITE( debug_output_unit, TRIM( write_format2 ) // ',L1)' )                              &
+             'write only by master rank', dimensions(i)%write_only_by_master_rank
           WRITE( debug_output_unit, TRIM( write_format2 ) // ',I7)' )                              &
              'length', dimensions(i)%length
@@ -4080,5 +4185,5 @@
     SUBROUTINE print_variables( indent_level, variables )
 
-       INTEGER, PARAMETER  ::  max_keyname_length = 16  !< length of longest key name
+       INTEGER, PARAMETER ::  max_keyname_length = 26  !< length of longest key name
 
        CHARACTER(LEN=50) ::  write_format1  !< format for write statements
@@ -4111,5 +4216,5 @@
              'id', variables(i)%id
           WRITE( debug_output_unit, TRIM( write_format2 ) // ',L1)' )                              &
-             'is global', variables(i)%is_global
+             'write only by master rank', variables(i)%write_only_by_master_rank
 
           WRITE( debug_output_unit, TRIM( write_format2 ) // ',A)', ADVANCE='no' )                 &
Index: palm/trunk/SOURCE/data_output_netcdf4_module.f90
===================================================================
--- palm/trunk/SOURCE/data_output_netcdf4_module.f90	(revision 4596)
+++ palm/trunk/SOURCE/data_output_netcdf4_module.f90	(revision 4597)
@@ -24,4 +24,10 @@
 ! -----------------
 ! $Id$
+! bugfix: - allow writing of unlimited dimensions in parallel mode
+!         - prevent unused-variable warning if preprocessor directives are not given
+! change: - set parallel access mode to independent per default
+! new   : - dimension variables can be written by every PE
+!
+! 4579 2020-06-25 20:05:07Z gronemeier
 ! corrected formatting to follow PALM coding standard
 !
@@ -53,4 +59,7 @@
 !> NetCDF output module to write data to NetCDF files.
 !> This is either done in parallel mode via parallel NetCDF4 I/O or in serial mode only by PE0.
+!>
+!> @bug 'mode' is not always checked. If a routine is called with an unknown mode (e.g. a typo),
+!>      this does not throw any error.
 !--------------------------------------------------------------------------------------------------!
  MODULE data_output_netcdf4_module
@@ -82,4 +91,5 @@
     INTEGER ::  global_id_in_file = -1  !< value of global ID within a file
     INTEGER ::  master_rank             !< master rank for tasks to be executed by single PE only
+    INTEGER ::  my_rank                 !< MPI rank of processor
     INTEGER ::  output_group_comm       !< MPI communicator addressing all MPI ranks which participate in output
 
@@ -150,4 +160,6 @@
                                  program_debug_output_unit, debug_output, dom_global_id )
 
+    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_init_module'  !< name of this routine
+
     CHARACTER(LEN=*), INTENT(IN) ::  file_suffix_of_output_group  !> file-name suffix added to each file;
                                                                   !> must be unique for each output group
@@ -157,4 +169,5 @@
     INTEGER, INTENT(IN) ::  mpi_comm_of_output_group   !< MPI communicator specifying the rank group participating in output
     INTEGER, INTENT(IN) ::  program_debug_output_unit  !< file unit number for debug output
+    INTEGER             ::  return_value               !< return value
 
     LOGICAL, INTENT(IN) ::  debug_output  !< if true, debug output is printed
@@ -165,4 +178,17 @@
     master_rank = master_output_rank
 
+#if defined( __parallel )
+    CALL MPI_COMM_RANK( output_group_comm, my_rank, return_value )
+    IF ( return_value /= 0 )  THEN
+       CALL internal_message( 'error', routine_name // ': MPI_COMM_RANK error' )
+    ENDIF
+#else
+    my_rank = master_rank
+    return_value = 0
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  CALL internal_message( 'debug', routine_name // ': dummy message' )
+#endif
+
     debug_output_unit = program_debug_output_unit
     print_debug_output = debug_output
@@ -185,5 +211,4 @@
 
     INTEGER, INTENT(OUT) ::  file_id       !< file ID
-    INTEGER              ::  my_rank       !< MPI rank of processor
     INTEGER              ::  nc_stat       !< netcdf return value
     INTEGER, INTENT(OUT) ::  return_value  !< return value
@@ -199,24 +224,14 @@
 
 #if defined( __netcdf4 )
-#if defined( __parallel )
-       CALL MPI_COMM_RANK( output_group_comm, my_rank, return_value )
-       IF ( return_value /= 0 )  THEN
-          CALL internal_message( 'error', routine_name // ': MPI_COMM_RANK error' )
-       ENDIF
-       IF ( my_rank /= master_rank )  THEN
-          return_value = 1
-          CALL internal_message( 'error', routine_name //                                          &
-                                 ': trying to define a NetCDF file in serial mode by an MPI ' //   &
-                                 'rank other than the master output rank. Serial NetCDF ' //       &
-                                 'files can only be defined by the master output rank!' )
-       ENDIF
-#else
-       my_rank = master_rank
-       return_value = 0
-#endif
-
-       IF ( return_value == 0 )                                                                    &
-          nc_stat = NF90_CREATE( TRIM( file_name ) // TRIM( file_suffix ),                         &
-                                 IOR( NF90_NOCLOBBER, NF90_NETCDF4 ), file_id )
+
+       IF ( return_value == 0 )  THEN
+          IF ( my_rank == master_rank )  THEN
+             nc_stat = NF90_CREATE( TRIM( file_name ) // TRIM( file_suffix ),                      &
+                                    IOR( NF90_NOCLOBBER, NF90_NETCDF4 ),                           &
+                                    file_id )
+          ELSE
+             nc_stat = 0
+          ENDIF
+       ENDIF
 #else
        nc_stat = 0
@@ -245,7 +260,7 @@
        nc_stat = 0
        return_value = 1
-       CALL internal_message( 'error', routine_name // ': selected mode "' //                      &
-                                       TRIM( mode ) // '" must be either "' //                     &
-                                       mode_serial // '" or "' // mode_parallel // '"' )
+       CALL internal_message( 'error', routine_name //                                             &
+                              ': selected mode "' // TRIM( mode ) // '" must be either "' //       &
+                              mode_serial // '" or "' // mode_parallel // '"' )
     ENDIF
 
@@ -266,5 +281,5 @@
 !> Write attribute to netcdf file.
 !--------------------------------------------------------------------------------------------------!
- SUBROUTINE netcdf4_write_attribute( file_id, variable_id, attribute_name,                         &
+ SUBROUTINE netcdf4_write_attribute( mode, file_id, variable_id, attribute_name,                   &
                                      value_char, value_int8, value_int16, value_int32,             &
                                      value_real32, value_real64, return_value )
@@ -273,4 +288,5 @@
 
     CHARACTER(LEN=*), INTENT(IN)           ::  attribute_name  !< name of attribute
+    CHARACTER(LEN=*), INTENT(IN)           ::  mode            !< operation mode (either parallel or serial)
     CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  value_char      !< value of attribute
 
@@ -292,41 +308,52 @@
     return_value = 0
 
-    IF ( variable_id == global_id_in_file )  THEN
-       target_id = NF90_GLOBAL
-    ELSE
-       target_id = variable_id
-    ENDIF
-
-    CALL internal_message( 'debug', routine_name //                                                &
-                           ': write attribute "' // TRIM( attribute_name ) // '"' )
-
-    IF ( PRESENT( value_char ) )  THEN
-       nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), TRIM( value_char ) )
-    ELSEIF ( PRESENT( value_int8 ) )  THEN
-       nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_int8 )
-    ELSEIF ( PRESENT( value_int16 ) )  THEN
-       nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_int16 )
-    ELSEIF ( PRESENT( value_int32 ) )  THEN
-       nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_int32 )
-    ELSEIF ( PRESENT( value_real32 ) )  THEN
-       nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_real32 )
-    ELSEIF ( PRESENT( value_real64 ) )  THEN
-       nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_real64 )
-    ELSE
-       return_value = 1
-       CALL internal_message( 'error', routine_name //                                             &
-                              ': no value given for attribute "' // TRIM( attribute_name ) // '"' )
-    ENDIF
-
-    IF ( return_value == 0 )  THEN
-       IF ( nc_stat /= NF90_NOERR )  THEN
+    IF ( .NOT. ( TRIM( mode ) == mode_serial  .AND.  my_rank /= master_rank ) )  THEN
+
+       IF ( variable_id == global_id_in_file )  THEN
+          target_id = NF90_GLOBAL
+       ELSE
+          target_id = variable_id
+       ENDIF
+
+       CALL internal_message( 'debug', routine_name //                                             &
+                              ': write attribute "' // TRIM( attribute_name ) // '"' )
+
+       IF ( PRESENT( value_char ) )  THEN
+          nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), TRIM( value_char ) )
+       ELSEIF ( PRESENT( value_int8 ) )  THEN
+          nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_int8 )
+       ELSEIF ( PRESENT( value_int16 ) )  THEN
+          nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_int16 )
+       ELSEIF ( PRESENT( value_int32 ) )  THEN
+          nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_int32 )
+       ELSEIF ( PRESENT( value_real32 ) )  THEN
+          nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_real32 )
+       ELSEIF ( PRESENT( value_real64 ) )  THEN
+          nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( attribute_name ), value_real64 )
+       ELSE
           return_value = 1
           CALL internal_message( 'error', routine_name //                                          &
-                                 ': NetCDF error while writing attribute "' //                     &
-                                 TRIM( attribute_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-       ENDIF
+                                 ': no value given for attribute "' // TRIM( attribute_name ) //   &
+                                 '"' )
+       ENDIF
+
+       IF ( return_value == 0 )  THEN
+          IF ( nc_stat /= NF90_NOERR )  THEN
+             return_value = 1
+             CALL internal_message( 'error', routine_name //                                       &
+                                    ': NetCDF error while writing attribute "' //                  &
+                                    TRIM( attribute_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+          ENDIF
+       ENDIF
+
     ENDIF
 #else
     return_value = 1
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  THEN
+       nc_stat = LEN( routine_name )
+       target_id = 0
+    ENDIF
 #endif
 
@@ -339,5 +366,6 @@
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE netcdf4_init_dimension( mode, file_id, dimension_id, variable_id,                      &
-                                    dimension_name, dimension_type, dimension_length, return_value )
+                                    dimension_name, dimension_type, dimension_length,              &
+                                    write_only_by_master_rank, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_init_dimension'  !< name of this routine
@@ -355,33 +383,42 @@
     INTEGER, INTENT(OUT) ::  variable_id          !< variable ID
 
+    LOGICAL, INTENT(IN) ::  write_only_by_master_rank  !< true if only master rank shall write variable
+
 
 #if defined( __netcdf4 )
     return_value = 0
     variable_id = -1
-
-    CALL internal_message( 'debug', routine_name //                                                &
-                           ': init dimension "' // TRIM( dimension_name ) // '"' )
-!
-!-- Check if dimension is unlimited
-    IF ( dimension_length < 0 )  THEN
-       nc_dimension_length = NF90_UNLIMITED
-    ELSE
-       nc_dimension_length = dimension_length
-    ENDIF
-!
-!-- Define dimension in file
-    nc_stat = NF90_DEF_DIM( file_id, dimension_name, nc_dimension_length, dimension_id )
-
-    IF ( nc_stat == NF90_NOERR )  THEN
-!
-!--    Define variable holding dimension values in file
-       CALL netcdf4_init_variable( mode, file_id, variable_id, dimension_name, dimension_type,     &
-                                   (/ dimension_id /), is_global=.TRUE., return_value=return_value )
-
-    ELSE
-       return_value = 1
-       CALL internal_message( 'error', routine_name //                                             &
-                              ': NetCDF error while initializing dimension "' //                   &
-                              TRIM( dimension_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+    dimension_id = -1
+
+    IF ( .NOT. ( TRIM( mode ) == mode_serial  .AND.  my_rank /= master_rank ) )  THEN
+
+       CALL internal_message( 'debug', routine_name //                                             &
+                              ': init dimension "' // TRIM( dimension_name ) // '"' )
+!
+!--    Check if dimension is unlimited
+       IF ( dimension_length < 0 )  THEN
+          nc_dimension_length = NF90_UNLIMITED
+       ELSE
+          nc_dimension_length = dimension_length
+       ENDIF
+!
+!--    Define dimension in file
+       nc_stat = NF90_DEF_DIM( file_id, dimension_name, nc_dimension_length, dimension_id )
+
+       IF ( nc_stat == NF90_NOERR )  THEN
+!
+!--       Define variable holding dimension values in file
+          CALL netcdf4_init_variable( mode, file_id, variable_id, dimension_name, dimension_type,  &
+                                      (/ dimension_id /),                                          &
+                                      write_only_by_master_rank=write_only_by_master_rank,         &
+                                      return_value=return_value )
+
+       ELSE
+          return_value = 1
+          CALL internal_message( 'error', routine_name //                                          &
+                                 ': NetCDF error while initializing dimension "' //                &
+                                 TRIM( dimension_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+       ENDIF
+
     ENDIF
 #else
@@ -389,4 +426,10 @@
     variable_id = -1
     dimension_id = -1
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  THEN
+       nc_stat = LEN( routine_name )
+       nc_dimension_length = 0
+    ENDIF
 #endif
 
@@ -399,5 +442,5 @@
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE netcdf4_init_variable( mode, file_id, variable_id, variable_name, variable_type,       &
-                                   dimension_ids, is_global, return_value )
+                                   dimension_ids, write_only_by_master_rank, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_init_variable'  !< name of this routine
@@ -407,53 +450,77 @@
     CHARACTER(LEN=*), INTENT(IN) ::  variable_type  !< data type of variable
 
-    INTEGER, INTENT(IN)  ::  file_id           !< file ID
-    INTEGER              ::  nc_stat           !< netcdf return value
-    INTEGER              ::  nc_variable_type  !< netcdf data type
-    INTEGER, INTENT(OUT) ::  return_value      !< return value
-    INTEGER, INTENT(OUT) ::  variable_id       !< variable ID
-
+    INTEGER, INTENT(IN)  ::  file_id                 !< file ID
+    INTEGER              ::  nc_stat                 !< netcdf return value
+    INTEGER              ::  nc_variable_type        !< netcdf data type
+    INTEGER, INTENT(OUT) ::  return_value            !< return value
+    INTEGER, INTENT(OUT) ::  variable_id             !< variable ID
+#if defined( __netcdf4_parallel )
+    INTEGER              ::  parallel_access_mode    !< either NF90_INDEPENDENT or NF90_COLLECTIVE
+    INTEGER              ::  unlimited_dimension_id  !< ID of unlimited dimension in file
+#endif
     INTEGER, DIMENSION(:), INTENT(IN) ::  dimension_ids  !< list of dimension IDs used by variable
 
-    LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global (same on all PE)
+    LOGICAL, INTENT(IN) ::  write_only_by_master_rank  !< true if only master rank shall write variable
 
 
 #if defined( __netcdf4 )
     return_value = 0
-
-    WRITE( temp_string, * ) is_global
-    CALL internal_message( 'debug', routine_name //                                                &
-                           ': init variable "' // TRIM( variable_name ) //                         &
-                           '" ( is_global = ' // TRIM( temp_string ) // ')' )
-
-    nc_variable_type = get_netcdf_data_type( variable_type )
-
-    IF ( nc_variable_type /= -1 )  THEN
-!
-!--    Define variable in file
-       nc_stat = NF90_DEF_VAR( file_id, variable_name, nc_variable_type, dimension_ids, variable_id )
-
-!
-!--    Define how variable can be accessed by PEs in parallel netcdf file
-       IF ( nc_stat == NF90_NOERR  .AND.  TRIM( mode ) == mode_parallel )  THEN
+    variable_id = -1
+
+    IF ( ( TRIM( mode ) == mode_serial  .AND.  my_rank == master_rank )                            &
+         .OR.  TRIM( mode ) == mode_parallel )  THEN
+
+       WRITE( temp_string, * ) write_only_by_master_rank
+       CALL internal_message( 'debug', routine_name //                                             &
+                              ': init variable "' // TRIM( variable_name ) //                      &
+                              '" ( write_only_by_master_rank = ' // TRIM( temp_string ) // ')' )
+
+       nc_variable_type = get_netcdf_data_type( variable_type )
+
+       IF ( nc_variable_type /= -1 )  THEN
+!
+!--       Define variable in file
+          nc_stat = NF90_DEF_VAR( file_id, variable_name, nc_variable_type,                        &
+                                  dimension_ids, variable_id )
+
 #if defined( __netcdf4_parallel )
-          IF ( is_global )  THEN
-             nc_stat = NF90_VAR_PAR_ACCESS( file_id, variable_id, NF90_INDEPENDENT )
-          ELSE
-             nc_stat = NF90_VAR_PAR_ACCESS( file_id, variable_id, NF90_COLLECTIVE )
+!
+!--       Define how variable can be accessed by PEs in parallel netcdf file
+          IF ( nc_stat == NF90_NOERR  .AND.  TRIM( mode ) == mode_parallel )  THEN
+!
+!--          If the variable uses an unlimited dimension, its access mode must be 'collective',
+!--          otherwise it can be set to independent.
+!--          Hence, get ID of unlimited dimension in file (if any) and check if it is used by
+!--          the variable.
+             nc_stat = NF90_INQUIRE( file_id, UNLIMITEDDIMID=unlimited_dimension_id )
+
+             IF ( nc_stat == NF90_NOERR )  THEN
+                IF ( ANY( dimension_ids == unlimited_dimension_id ) )  THEN
+                   parallel_access_mode = NF90_COLLECTIVE
+                ELSE
+                   parallel_access_mode = NF90_INDEPENDENT
+                ENDIF
+
+                nc_stat = NF90_VAR_PAR_ACCESS( file_id, variable_id, parallel_access_mode )
+             ENDIF
           ENDIF
-#else
-          CONTINUE
-#endif
-       ENDIF
-
-       IF ( nc_stat /= NF90_NOERR )  THEN
+#endif
+
+          IF ( nc_stat /= NF90_NOERR )  THEN
+             return_value = 1
+             CALL internal_message( 'error', routine_name //                                       &
+                                    ': NetCDF error while initializing variable "' //              &
+                                    TRIM( variable_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+          ENDIF
+
+       ELSE
           return_value = 1
-          CALL internal_message( 'error', routine_name //                                          &
-                                 ': NetCDF error while initializing variable "' //                 &
-                                 TRIM( variable_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-       ENDIF
-
-    ELSE
+       ENDIF
+
+    ELSEIF ( TRIM( mode ) /= mode_serial  .AND.  TRIM( mode ) /= mode_parallel )  THEN
        return_value = 1
+       CALL internal_message( 'error', routine_name //                                             &
+                              ': selected mode "' // TRIM( mode ) // '" must be either "' //       &
+                              mode_serial // '" or "' // mode_parallel // '"' )
     ENDIF
 
@@ -461,4 +528,10 @@
     return_value = 1
     variable_id = -1
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  THEN
+       nc_stat = LEN( routine_name )
+       nc_variable_type = get_netcdf_data_type( '' )
+    ENDIF
 #endif
 
@@ -470,7 +543,9 @@
 !> Leave file definition state.
 !--------------------------------------------------------------------------------------------------!
- SUBROUTINE netcdf4_stop_file_header_definition( file_id, return_value )
+ SUBROUTINE netcdf4_stop_file_header_definition( mode, file_id, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_stop_file_header_definition'  !< name of this routine
+
+    CHARACTER(LEN=*), INTENT(IN) ::  mode  !< operation mode (either parallel or serial)
 
     INTEGER, INTENT(IN)  ::  file_id        !< file ID
@@ -483,22 +558,32 @@
     return_value = 0
 
-    WRITE( temp_string, * ) file_id
-    CALL internal_message( 'debug', routine_name //                                                &
-                           ': finalize file definition (file_id=' // TRIM( temp_string ) // ')' )
-!
-!-- Set general no fill, otherwise the performance drops significantly
-    nc_stat = NF90_SET_FILL( file_id, NF90_NOFILL, old_fill_mode )
-
-    IF ( nc_stat == NF90_NOERR )  THEN
-       nc_stat = NF90_ENDDEF( file_id )
-    ENDIF
-
-    IF ( nc_stat /= NF90_NOERR )  THEN
-       return_value = 1
-       CALL internal_message( 'error', routine_name //                                             &
-                              ': NetCDF error: ' // NF90_STRERROR( nc_stat ) )
+    IF ( .NOT. ( TRIM( mode ) == mode_serial  .AND.  my_rank /= master_rank ) )  THEN
+
+       WRITE( temp_string, * ) file_id
+       CALL internal_message( 'debug', routine_name //                                             &
+                              ': finalize file definition (file_id=' // TRIM( temp_string ) // ')' )
+!
+!--    Set general no fill, otherwise the performance drops significantly
+       nc_stat = NF90_SET_FILL( file_id, NF90_NOFILL, old_fill_mode )
+
+       IF ( nc_stat == NF90_NOERR )  THEN
+          nc_stat = NF90_ENDDEF( file_id )
+       ENDIF
+
+       IF ( nc_stat /= NF90_NOERR )  THEN
+          return_value = 1
+          CALL internal_message( 'error', routine_name //                                          &
+                                 ': NetCDF error: ' // NF90_STRERROR( nc_stat ) )
+       ENDIF
+
     ENDIF
 #else
     return_value = 1
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  THEN
+       nc_stat = LEN( routine_name )
+       old_fill_mode = 0
+    ENDIF
 #endif
 
@@ -511,6 +596,6 @@
 !--------------------------------------------------------------------------------------------------!
  SUBROUTINE netcdf4_write_variable(                                                                &
-               file_id, variable_id, bounds_start, value_counts, bounds_origin,                    &
-               is_global,                                                                          &
+               mode, file_id, variable_id, bounds_start, value_counts, bounds_origin,              &
+               write_only_by_master_rank,                                                          &
                values_char_0d,   values_char_1d,   values_char_2d,   values_char_3d,               &
                values_int8_0d,   values_int8_1d,   values_int8_2d,   values_int8_3d,               &
@@ -525,4 +610,6 @@
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_write_variable'  !< name of this routine
 
+    CHARACTER(LEN=*), INTENT(IN) ::  mode  !< operation mode (either parallel or serial)
+
     CHARACTER(LEN=1), POINTER,             INTENT(IN), OPTIONAL                   ::  values_char_0d  !< output variable
     CHARACTER(LEN=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  values_char_1d  !< output variable
@@ -530,11 +617,11 @@
     CHARACTER(LEN=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  values_char_3d  !< output variable
 
-    INTEGER              ::  d             !< loop index
-    INTEGER, INTENT(IN)  ::  file_id       !< file ID
-    INTEGER              ::  my_rank       !< MPI rank of processor
-    INTEGER              ::  nc_stat       !< netcdf return value
-    INTEGER              ::  ndims         !< number of dimensions of variable in file
-    INTEGER, INTENT(OUT) ::  return_value  !< return value
-    INTEGER, INTENT(IN)  ::  variable_id   !< variable ID
+    INTEGER              ::  d                       !< loop index
+    INTEGER, INTENT(IN)  ::  file_id                 !< file ID
+    INTEGER              ::  nc_stat                 !< netcdf return value
+    INTEGER              ::  ndims                   !< number of dimensions of variable in file
+    INTEGER, INTENT(OUT) ::  return_value            !< return value
+    INTEGER              ::  unlimited_dimension_id  !< ID of unlimited dimension in file
+    INTEGER, INTENT(IN)  ::  variable_id             !< variable ID
 
     INTEGER, DIMENSION(:),              INTENT(IN)  ::  bounds_origin      !< starting index of each dimension
@@ -561,5 +648,6 @@
     INTEGER(iwp),    POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  values_intwp_3d  !< output variable
 
-    LOGICAL, INTENT(IN) ::  is_global  !< true if variable is global (same on all PE)
+    LOGICAL, INTENT(IN) ::  write_only_by_master_rank  !< true if only master rank shall write variable
+    LOGICAL             ::  write_data                 !< true if variable shall be written to file
 
     REAL(KIND=4), POINTER,             INTENT(IN), OPTIONAL                   ::  values_real32_0d  !< output variable
@@ -578,16 +666,44 @@
 
 #if defined( __netcdf4 )
-
-#if defined( __parallel )
-    CALL MPI_COMM_RANK( output_group_comm, my_rank, return_value )
-    IF ( return_value /= 0 )  THEN
-       CALL internal_message( 'error', routine_name // ': MPI_COMM_RANK error' )
-    ENDIF
-#else
-    my_rank = master_rank
     return_value = 0
-#endif
-
-    IF ( return_value == 0  .AND.  ( .NOT. is_global .OR. my_rank == master_rank ) )  THEN
+    write_data = .FALSE.
+!
+!-- Check whether this PE write any data to file
+    IF ( TRIM( mode ) == mode_serial )  THEN
+
+       IF ( my_rank == master_rank )  write_data = .TRUE.
+
+    ELSEIF ( TRIM( mode ) == mode_parallel )  THEN
+!
+!--    Check for collective access mode.
+!--    This cannot be checked directly but indirect via the presence of any unlimited dimensions
+!--    If any dimension is unlimited, variable access must be collective and all PEs must
+!--    participate in writing
+       ndims = SIZE( bounds_start )
+       ALLOCATE( dimension_ids(ndims) )
+
+       nc_stat = NF90_INQUIRE_VARIABLE( file_id, variable_id, DIMIDS=dimension_ids )
+       nc_stat = NF90_INQUIRE( file_id, UNLIMITEDDIMID=unlimited_dimension_id )
+
+       IF ( ANY( dimension_ids == unlimited_dimension_id ) )  THEN
+          write_data = .TRUE.
+!
+!--    If access is independent, check if only master rank shall write
+       ELSEIF ( write_only_by_master_rank )  THEN
+          IF ( my_rank == master_rank )  write_data = .TRUE.
+!
+!--    If all PEs can write, check if there are any data to be written
+       ELSEIF ( ALL( value_counts > 0, DIM=1 ) )  THEN
+          write_data = .TRUE.
+       ENDIF
+
+    ELSE
+       return_value = 1
+       CALL internal_message( 'error', routine_name //                                             &
+                              ': selected mode "' // TRIM( mode ) // '" must be either "' //       &
+                              mode_serial // '" or "' // mode_parallel // '"' )
+    ENDIF
+
+    IF ( write_data )  THEN
 
        WRITE( temp_string, * ) variable_id
@@ -595,7 +711,6 @@
 
        ndims = SIZE( bounds_start )
-
-!
-!--    character output
+!
+!--    Character output
        IF ( PRESENT( values_char_0d ) )  THEN
           nc_stat = NF90_PUT_VAR( file_id, variable_id, (/ values_char_0d /),                      &
@@ -723,5 +838,5 @@
                                   count = value_counts )
 !
-!--    working-precision real output
+!--    Working-precision real output
        ELSEIF ( PRESENT( values_realwp_0d ) )  THEN
           nc_stat = NF90_PUT_VAR( file_id, variable_id, (/ values_realwp_0d /),                    &
@@ -757,5 +872,5 @@
              WRITE( temp_string, * )  NF90_STRERROR( nc_stat )
 
-             ALLOCATE( dimension_ids(ndims) )
+             IF ( .NOT. ALLOCATED( dimension_ids ) )  ALLOCATE( dimension_ids(ndims) )
              ALLOCATE( dimension_lengths(ndims) )
 
@@ -793,4 +908,12 @@
 #else
     return_value = 1
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  THEN
+       nc_stat = LEN( routine_name )
+       IF ( write_data )  unlimited_dimension_id = 0
+       IF ( ALLOCATED( dimension_ids ) )  d = 0
+       IF ( ALLOCATED( dimension_lengths ) )  ndims = 0
+    ENDIF
 #endif
 
@@ -802,7 +925,9 @@
 !> Close netcdf file.
 !--------------------------------------------------------------------------------------------------!
- SUBROUTINE netcdf4_finalize( file_id, return_value )
+ SUBROUTINE netcdf4_finalize( mode, file_id, return_value )
 
     CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_finalize'  !< name of routine
+
+    CHARACTER(LEN=*), INTENT(IN) ::  mode  !< operation mode (either parallel or serial)
 
     INTEGER, INTENT(IN)  ::  file_id       !< file ID
@@ -812,18 +937,30 @@
 
 #if defined( __netcdf4 )
-    WRITE( temp_string, * ) file_id
-    CALL internal_message( 'debug', routine_name //                                                &
-                           ': close file (file_id=' // TRIM( temp_string ) // ')' )
-
-    nc_stat = NF90_CLOSE( file_id )
-    IF ( nc_stat == NF90_NOERR )  THEN
-       return_value = 0
-    ELSE
-       return_value = 1
-       CALL internal_message( 'error', routine_name //                                             &
-                              ': NetCDF error: ' // NF90_STRERROR( nc_stat ) )
+    return_value = 0
+
+    IF ( .NOT. ( TRIM( mode ) == mode_serial  .AND.  my_rank /= master_rank ) )  THEN
+
+       WRITE( temp_string, * ) file_id
+       CALL internal_message( 'debug', routine_name //                                             &
+                              ': close file (file_id=' // TRIM( temp_string ) // ')' )
+
+       nc_stat = NF90_CLOSE( file_id )
+       IF ( nc_stat == NF90_NOERR )  THEN
+          return_value = 0
+       ELSE
+          return_value = 1
+          CALL internal_message( 'error', routine_name //                                          &
+                                 ': NetCDF error: ' // NF90_STRERROR( nc_stat ) )
+       ENDIF
+
     ENDIF
 #else
     return_value = 1
+!
+!-- Dummy commands to prevent "unused-variable" warning if preprocessor is not set
+    IF ( .FALSE. )  THEN
+       nc_stat = 0
+       temp_string = routine_name
+    ENDIF
 #endif
 
