Index: /palm/trunk/SOURCE/Makefile
===================================================================
--- /palm/trunk/SOURCE/Makefile	(revision 4105)
+++ /palm/trunk/SOURCE/Makefile	(revision 4106)
@@ -605,6 +605,5 @@
 	data_output_binary_module.f90 \
 	data_output_module.f90 \
-	data_output_netcdf4_parallel_module.f90 \
-	data_output_netcdf4_serial_module.f90 \
+	data_output_netcdf4_module.f90 \
 	data_output_2d.f90 \
 	data_output_3d.f90 \
@@ -915,6 +914,5 @@
 data_output_module.o: \
 	data_output_binary_module.o \
-	data_output_netcdf4_parallel_module.o \
-	data_output_netcdf4_serial_module.o \
+	data_output_netcdf4_module.o \
 	mod_kinds.o
 data_output_mask.o: \
@@ -930,7 +928,5 @@
 	salsa_mod.o \
 	surface_mod.o
-data_output_netcdf4_parallel_module.o: \
-	mod_kinds.o
-data_output_netcdf4_serial_module.o: \
+data_output_netcdf4_module.o: \
 	mod_kinds.o
 data_output_profiles.o: \
Index: /palm/trunk/SOURCE/data_output_binary_module.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_binary_module.f90	(revision 4105)
+++ /palm/trunk/SOURCE/data_output_binary_module.f90	(revision 4106)
@@ -20,6 +20,6 @@
 ! Current revisions:
 ! ------------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
@@ -36,7 +36,5 @@
 !> Binary output module to write output data into binary files.
 !>
-!> @todo Think of removing 'is_init' as its value can be derived from the return
-!>       value of 'return_value'.
-!> @todo Get return value of write statements.
+!> @todo Get iostat value of write statements.
 !--------------------------------------------------------------------------------------------------!
 MODULE data_output_binary_module
@@ -57,4 +55,5 @@
 
    CHARACTER(LEN=*), PARAMETER ::  config_file_name = 'BINARY_TO_NETCDF_CONFIG'  !< name of config file
+   CHARACTER(LEN=*), PARAMETER ::  mode_binary = 'binary'                        !< string to select operation mode of module
    CHARACTER(LEN=*), PARAMETER ::  prefix = 'BIN_'                               !< file prefix for binary files
 
@@ -156,9 +155,10 @@
 !> Open binary file.
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE binary_open_file( filename, file_id, return_value )
+SUBROUTINE binary_open_file( mode, filename, file_id, return_value )
 
    CHARACTER(LEN=charlen)             ::  bin_filename = ''  !< actual name of binary file
    CHARACTER(LEN=charlen), INTENT(IN) ::  filename           !< name of file
    CHARACTER(LEN=7)                   ::  myid_char          !< string containing value of myid with leading zeros
+   CHARACTER(LEN=*),       INTENT(IN) ::  mode               !< operation mode
 
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_open_file'  !< name of this routine
@@ -180,5 +180,5 @@
       WRITE( myid_char, '("_",I6.6)' )  myid
    ELSE
-      CALL internal_message( 'debug', routine_name // 'MPI_COMM_RANK error' )
+      CALL internal_message( 'debug', routine_name // ': MPI_COMM_RANK error' )
    ENDIF
 #else
@@ -186,4 +186,7 @@
    myid_char = '_' // REPEAT('0', 6)
 #endif
+
+   !-- Check mode (not required, added for compatibility reasons)
+   IF ( TRIM( mode ) == mode_binary )  CONTINUE
 
    !-- Open binary config file for combining script
@@ -356,5 +359,5 @@
       return_value = 1
       CALL internal_message( 'error', TRIM( routine_name ) // &
-                                      ': attribute "' // TRIM( att_name ) // '": no value given' )
+                             ': attribute "' // TRIM( att_name ) // '": no value given' )
    ENDIF
 
@@ -367,10 +370,11 @@
 !> values to be later written to file.
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE binary_init_dimension( file_id, dim_id, var_id, &
-              dim_name, dim_type, dim_length, is_init, return_value )
+SUBROUTINE binary_init_dimension( mode, file_id, dim_id, var_id, &
+              dim_name, dim_type, dim_length, return_value )
 
    CHARACTER(LEN=charlen), INTENT(IN) ::  dim_name  !< name of dimension
    CHARACTER(LEN=charlen), INTENT(IN) ::  dim_type  !< data type of dimension
    CHARACTER(LEN=charlen)             ::  out_str   !< output string
+   CHARACTER(LEN=*),       INTENT(IN) ::  mode      !< operation mode
 
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_init_dimension'  !< name of this routine
@@ -382,10 +386,11 @@
    INTEGER(iwp), INTENT(OUT) ::  var_id        !< variable ID
 
-   LOGICAL, INTENT(OUT) ::  is_init  !< true if dimension is initialized
-
 
    return_value = 0
 
    CALL internal_message( 'debug', routine_name // ': init dimension ' // TRIM( dim_name ) )
+
+   !-- Check mode (not required, added for compatibility reasons only)
+   IF ( TRIM( mode ) == mode_binary )  CONTINUE
 
    !-- Assign dimension ID
@@ -402,8 +407,7 @@
 
    !-- Define variable associated with dimension
-   CALL binary_init_variable( file_id, var_id, dim_name, dim_type, &
-                              (/dim_id/), is_init, .TRUE., return_value )
+   CALL binary_init_variable( mode, file_id, var_id, dim_name, dim_type, (/dim_id/), &
+                              is_global=.TRUE., return_value=return_value )
    IF ( return_value /= 0 )  THEN
-      is_init = .FALSE.
       CALL internal_message( 'error', routine_name // &
                                       ': init dimension "' // TRIM( dim_name ) // '"' )
@@ -417,10 +421,11 @@
 !> Initialize variable. Write information of variable into file header.
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE binary_init_variable( file_id, var_id, var_name, var_type, &
-                                 var_dim_ids, is_init, is_global, return_value )
+SUBROUTINE binary_init_variable( mode, file_id, var_id, var_name, var_type, &
+                                 var_dim_ids, is_global, return_value )
 
    CHARACTER(LEN=charlen)             ::  out_str   !< output string
    CHARACTER(LEN=charlen), INTENT(IN) ::  var_name  !< name of variable
    CHARACTER(LEN=charlen), INTENT(IN) ::  var_type  !< data type of variable
+   CHARACTER(LEN=*),       INTENT(IN) ::  mode      !< operation mode
 
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_init_variable'  !< name of this routine
@@ -433,5 +438,4 @@
 
    LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global (same on all PE)
-   LOGICAL, INTENT(OUT) ::  is_init    !< true if variable is initialized
 
 
@@ -440,5 +444,9 @@
    CALL internal_message( 'debug', routine_name // ': init variable ' // TRIM( var_name ) )
 
-   IF ( is_global )  CONTINUE  ! reqired to prevent compiler warning
+   !-- Check mode (not required, added for compatibility reasons only)
+   IF ( TRIM( mode ) == mode_binary )  CONTINUE
+
+   !-- Check if variable is global (not required, added for compatibility reasons only)
+   IF ( is_global )  CONTINUE
 
    !-- Assign variable ID
@@ -454,7 +462,4 @@
    WRITE( file_id )  SIZE( var_dim_ids )
    WRITE( file_id )  var_dim_ids
-
-   !-- Variable is initialised
-   is_init = return_value == 0
 
 END SUBROUTINE binary_init_variable
@@ -504,4 +509,6 @@
               return_value )
 
+   CHARACTER(LEN=charlen) ::  out_str  !< output string
+
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'binary_write_variable'  !< name of this routine
 
@@ -567,70 +574,124 @@
       !-- 8bit integer output
       IF ( PRESENT( var_int8_0d ) )  THEN
+         out_str = 'int8'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int8_0d
       ELSEIF ( PRESENT( var_int8_1d ) )  THEN
+         out_str = 'int8'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int8_1d
       ELSEIF ( PRESENT( var_int8_2d ) )  THEN
+         out_str = 'int8'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int8_2d
       ELSEIF ( PRESENT( var_int8_3d ) )  THEN
+         out_str = 'int8'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int8_3d
       !-- 16bit integer output
       ELSEIF ( PRESENT( var_int16_0d ) )  THEN
+         out_str = 'int16'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int16_0d
       ELSEIF ( PRESENT( var_int16_1d ) )  THEN
+         out_str = 'int16'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int16_1d
       ELSEIF ( PRESENT( var_int16_2d ) )  THEN
+         out_str = 'int16'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int16_2d
       ELSEIF ( PRESENT( var_int16_3d ) )  THEN
+         out_str = 'int16'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int16_3d
       !-- 32bit integer output
       ELSEIF ( PRESENT( var_int32_0d ) )  THEN
+         out_str = 'int32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int32_0d
       ELSEIF ( PRESENT( var_int32_1d ) )  THEN
+         out_str = 'int32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int32_1d
       ELSEIF ( PRESENT( var_int32_2d ) )  THEN
+         out_str = 'int32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int32_2d
       ELSEIF ( PRESENT( var_int32_3d ) )  THEN
+         out_str = 'int32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_int32_3d
       !-- working-precision integer output
       ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
+         out_str = 'intwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_intwp_0d
       ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
+         out_str = 'intwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_intwp_1d
       ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
+         out_str = 'intwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_intwp_2d
       ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
+         out_str = 'intwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_intwp_3d
       !-- 32bit real output
       ELSEIF ( PRESENT( var_real32_0d ) )  THEN
+         out_str = 'real32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real32_0d
       ELSEIF ( PRESENT( var_real32_1d ) )  THEN
+         out_str = 'real32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real32_1d
       ELSEIF ( PRESENT( var_real32_2d ) )  THEN
+         out_str = 'real32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real32_2d
       ELSEIF ( PRESENT( var_real32_3d ) )  THEN
+         out_str = 'real32'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real32_3d
       !-- 64bit real output
       ELSEIF ( PRESENT( var_real64_0d ) )  THEN
+         out_str = 'real64'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real64_0d
       ELSEIF ( PRESENT( var_real64_1d ) )  THEN
+         out_str = 'real64'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real64_1d
       ELSEIF ( PRESENT( var_real64_2d ) )  THEN
+         out_str = 'real64'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real64_2d
       ELSEIF ( PRESENT( var_real64_3d ) )  THEN
+         out_str = 'real64'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_real64_3d
       !-- working-precision real output
       ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
+         out_str = 'realwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_realwp_0d
       ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
+         out_str = 'realwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_realwp_1d
       ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
+         out_str = 'realwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_realwp_2d
       ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
+         out_str = 'realwp'
+         WRITE( file_id )  out_str
          WRITE( file_id )  var_realwp_3d
       ELSE
          return_value = 1
-         WRITE( temp_string, '(": variable_id=",I6,", file_id=",I6)' ) var_id, file_id
-         CALL internal_message( 'error', routine_name // &
-                                         TRIM( temp_string ) // ': no values given' )
+         CALL internal_message( 'error', routine_name // ': no values given' )
       ENDIF
 
@@ -706,5 +767,5 @@
    IF ( TRIM( level ) == 'error' )  THEN
 
-      WRITE( internal_error_message, '(A,A)' ) 'DOM ERROR: ', string
+      WRITE( internal_error_message, '(A,A)' ) ': ', string
 
    ELSEIF ( TRIM( level ) == 'debug'  .AND.  print_debug_output )  THEN
Index: /palm/trunk/SOURCE/data_output_module.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_module.f90	(revision 4105)
+++ /palm/trunk/SOURCE/data_output_module.f90	(revision 4106)
@@ -20,6 +20,6 @@
 ! Current revisions:
 ! ------------------
-! 
-! 
+!
+!
 ! Former revisions:
 ! -----------------
@@ -43,7 +43,4 @@
 !>
 !> @todo Convert variable if type of given values do not fit specified type.
-!> @todo Remove unused variables
-!> @todo How to deal with definition calls after dom_start_output is called? Should it be allowed
-!>       to define new files after that (which is technically possible)?
 !> @todo Remove iwp from index (and similar) variables.
 !--------------------------------------------------------------------------------------------------!
@@ -52,25 +49,14 @@
    USE kinds
 
-   USE data_output_netcdf4_serial_module, &
-      ONLY: netcdf4_serial_init_dimension, &
-            netcdf4_serial_get_error_message, &
-            netcdf4_serial_init_end, &
-            netcdf4_serial_init_module, &
-            netcdf4_serial_init_variable, &
-            netcdf4_serial_finalize, &
-            netcdf4_serial_open_file, &
-            netcdf4_serial_write_attribute, &
-            netcdf4_serial_write_variable
-
-   USE data_output_netcdf4_parallel_module, &
-      ONLY: netcdf4_parallel_init_dimension, &
-            netcdf4_parallel_get_error_message, &
-            netcdf4_parallel_init_end, &
-            netcdf4_parallel_init_module, &
-            netcdf4_parallel_init_variable, &
-            netcdf4_parallel_finalize, &
-            netcdf4_parallel_open_file, &
-            netcdf4_parallel_write_attribute, &
-            netcdf4_parallel_write_variable
+   USE data_output_netcdf4_module, &
+      ONLY: netcdf4_init_dimension, &
+            netcdf4_get_error_message, &
+            netcdf4_init_end, &
+            netcdf4_init_module, &
+            netcdf4_init_variable, &
+            netcdf4_finalize, &
+            netcdf4_open_file, &
+            netcdf4_write_attribute, &
+            netcdf4_write_variable
 
    USE data_output_binary_module, &
@@ -105,5 +91,4 @@
       INTEGER(iwp)           ::  id = 0               !< id within file
       LOGICAL                ::  is_global = .FALSE.  !< true if global variable
-      LOGICAL                ::  is_init = .FALSE.    !< true if initialized
       CHARACTER(LEN=charlen), DIMENSION(:), ALLOCATABLE ::  dimension_names  !< list of dimension names
       INTEGER(iwp),           DIMENSION(:), ALLOCATABLE ::  dimension_ids    !< list of dimension ids
@@ -118,5 +103,4 @@
       INTEGER(iwp)           ::  length_mask          !< length of masked dimension
       INTEGER(iwp)           ::  var_id = 0           !< associated variable id within file
-      LOGICAL                ::  is_init = .FALSE.    !< true if initialized
       LOGICAL                ::  is_masked = .FALSE.  !< true if masked
       INTEGER(iwp),    DIMENSION(2)              ::  bounds                !< lower and upper bound of dimension
@@ -125,5 +109,5 @@
       INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE ::  masked_values_int16   !< masked dimension values if 16bit integer
       INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE ::  masked_values_int32   !< masked dimension values if 32bit integer
-      INTEGER(iwp),    DIMENSION(:), ALLOCATABLE ::  masked_values_intwp   !< masked dimension values if working-precision integer
+      INTEGER(iwp),    DIMENSION(:), ALLOCATABLE ::  masked_values_intwp   !< masked dimension values if working-precision int
       INTEGER(KIND=1), DIMENSION(:), ALLOCATABLE ::  values_int8           !< dimension values if 16bit integer
       INTEGER(KIND=2), DIMENSION(:), ALLOCATABLE ::  values_int16          !< dimension values if 16bit integer
@@ -252,7 +236,5 @@
    CALL binary_init_module( debug_output_unit, debug_output, no_var_id )
 
-   CALL netcdf4_serial_init_module( debug_output_unit, debug_output, no_var_id )
-
-   CALL netcdf4_parallel_init_module( debug_output_unit, debug_output, no_var_id )
+   CALL netcdf4_init_module( debug_output_unit, debug_output, no_var_id )
 
 END SUBROUTINE dom_init
@@ -310,5 +292,6 @@
    !             WRITE(*,'(10X,5(I5,1X),A)') files(f)%dimensions(d)%values_int32(0:MIN(4,files(f)%dimensions(d)%length)), '...'
    !          ELSE
-   !             WRITE(*,'(10X,5(F8.2,1X),A)') files(f)%dimensions(d)%values_real64(0:MIN(4,files(f)%dimensions(d)%length)), '...'
+   !             WRITE(*,'(10X,5(F8.2,1X),A)')  &
+   !                files(f)%dimensions(d)%values_real64(0:MIN(4,files(f)%dimensions(d)%length)), '...'
    !          ENDIF
    !          IF ( ALLOCATED(files(f)%dimensions(d)%mask) )  THEN
@@ -716,7 +699,7 @@
 
       return_value = 1
-      CALL internal_message( 'error', routine_name //                   &
-                                      ': dimension ' // TRIM( name ) // &
-                                      ': At least one but no more than two bounds must be given' )
+      CALL internal_message( 'error', routine_name //          &
+                             ': dimension ' // TRIM( name ) // &
+                             ': At least one but no more than two bounds must be given' )
 
    ENDIF
@@ -729,5 +712,13 @@
          IF ( TRIM( filename ) == files(f)%name )  THEN
 
-            IF ( .NOT. ALLOCATED( files(f)%dimensions ) )  THEN
+            IF ( files(f)%is_init )  THEN
+
+               return_value = 1
+               CALL internal_message( 'error',                           &
+                       routine_name // ': file "' // TRIM( filename ) // &
+                       '" is already initialized. No further dimension definition allowed!' )
+               EXIT
+
+            ELSEIF ( .NOT. ALLOCATED( files(f)%dimensions ) )  THEN
 
                ndim = 1
@@ -736,27 +727,45 @@
             ELSE
 
-               ndim = SIZE( files(f)%dimensions )
-
-               !-- Check if dimension already exists in file
-               DO  d = 1, ndim
-                  IF ( files(f)%dimensions(d)%name == dimension%name )  THEN
-                     return_value = 1
-                     CALL internal_message( 'error',            &
-                             routine_name //                    &
-                             ': dimension "' // TRIM( name ) // &
-                             '" already exists in file "' // TRIM( filename ) // '"' )
-                     EXIT
+               !-- Check if any variable of the same name as the new dimension is already defined
+               IF ( ALLOCATED( files(f)%variables ) )  THEN
+                  DO  i = 1, SIZE( files(f)%variables )
+                     IF ( files(f)%variables(i)%name == dimension%name )  THEN
+                        return_value = 1
+                        CALL internal_message( 'error', routine_name //                   &
+                                               ': file "' // TRIM( filename ) //          &
+                                               '" already has a variable of name "' //    &
+                                               TRIM( dimension%name ) // '" defined. ' // &
+                                               'Defining a dimension of the same ' //     &
+                                               'name is not allowed.' )
+                        EXIT
+                     ENDIF
+                  ENDDO
+               ENDIF
+
+               IF ( return_value == 0 )  THEN
+                  !-- Check if dimension already exists in file
+                  ndim = SIZE( files(f)%dimensions )
+
+                  DO  d = 1, ndim
+                     IF ( files(f)%dimensions(d)%name == dimension%name )  THEN
+                        return_value = 1
+                        CALL internal_message( 'error',            &
+                                routine_name //                    &
+                                ': dimension "' // TRIM( name ) // &
+                                '" already exists in file "' // TRIM( filename ) // '"' )
+                        EXIT
+                     ENDIF
+                  ENDDO
+
+                  !-- Extend dimension list
+                  IF ( return_value == 0 )  THEN
+                     ALLOCATE( dims_tmp(ndim) )
+                     dims_tmp = files(f)%dimensions
+                     DEALLOCATE( files(f)%dimensions )
+                     ndim = ndim + 1
+                     ALLOCATE( files(f)%dimensions(ndim) )
+                     files(f)%dimensions(:ndim-1) = dims_tmp
+                     DEALLOCATE( dims_tmp )
                   ENDIF
-               ENDDO
-
-               !-- Extend dimension list
-               IF ( return_value == 0 )  THEN
-                  ALLOCATE( dims_tmp(ndim) )
-                  dims_tmp = files(f)%dimensions
-                  DEALLOCATE( files(f)%dimensions )
-                  ndim = ndim + 1
-                  ALLOCATE( files(f)%dimensions(ndim) )
-                  files(f)%dimensions(:ndim-1) = dims_tmp
-                  DEALLOCATE( dims_tmp )
                ENDIF
 
@@ -832,26 +841,49 @@
       IF ( TRIM( filename ) == files(f)%name )  THEN
 
-         !-- Check if dimensions assigned to variable are defined within file
-         IF ( ALLOCATED( files(f)%dimensions ) )  THEN
-
-            DO  i = 1, SIZE( variable%dimension_names )
-               found = .FALSE.
-               DO  d = 1, SIZE( files(f)%dimensions )
-                  IF ( files(f)%dimensions(d)%name == variable%dimension_names(i) )  THEN
-                     found = .TRUE.
+         IF ( files(f)%is_init )  THEN
+
+            return_value = 1
+            CALL internal_message( 'error', routine_name // ': file "' // TRIM( filename ) // &
+                    '" is already initialized. No further variable definition allowed!' )
+            EXIT
+
+         ELSEIF ( ALLOCATED( files(f)%dimensions ) )  THEN
+
+            !-- Check if any dimension of the same name as the new variable is already defined
+            DO  d = 1, SIZE( files(f)%dimensions )
+               IF ( files(f)%dimensions(d)%name == variable%name )  THEN
+                  return_value = 1
+                  CALL internal_message( 'error', routine_name //                  &
+                                         ': file "' // TRIM( filename ) //         &
+                                         '" already has a dimension of name "' //  &
+                                         TRIM( variable%name ) // '" defined. ' // &
+                                         'Defining a variable of the same name is not allowed.' )
+                  EXIT
+               ENDIF
+            ENDDO
+
+            !-- Check if dimensions assigned to variable are defined within file
+            IF ( return_value == 0 )  THEN
+               DO  i = 1, SIZE( variable%dimension_names )
+                  found = .FALSE.
+                  DO  d = 1, SIZE( files(f)%dimensions )
+                     IF ( files(f)%dimensions(d)%name == variable%dimension_names(i) )  THEN
+                        found = .TRUE.
+                        EXIT
+                     ENDIF
+                  ENDDO
+                  IF ( .NOT. found )  THEN
+                     return_value = 1
+                     CALL internal_message( 'error',                               &
+                                            routine_name //                        &
+                                            ': variable "' // TRIM( name ) //      &
+                                            '" in file "' // TRIM( filename ) //   &
+                                            '": required dimension "' //           &
+                                            TRIM( variable%dimension_names(i) ) // &
+                                            '" not defined' )
                      EXIT
                   ENDIF
                ENDDO
-               IF ( .NOT. found )  THEN
-                  return_value = 1
-                  CALL internal_message( 'error', &
-                                         routine_name //                      &
-                                         ': variable "' // TRIM( name ) //    &
-                                         '" in file "' // TRIM( filename ) // &
-                                         '": required dimension "' //         &
-                                         TRIM( variable%dimension_names(i) ) // '" not defined' )
-                  EXIT
-               ENDIF
-            ENDDO
+            ENDIF
 
          ELSE
@@ -1263,4 +1295,11 @@
 
       IF ( TRIM( filename ) == files(f)%name )  THEN
+
+         IF ( files(f)%is_init )  THEN
+            return_value = 1
+            CALL internal_message( 'error', routine_name // ': file "' // TRIM( filename ) // &
+                    '" is already initialized. No further attribute definition allowed!' )
+            EXIT
+         ENDIF
 
          !-- Add attribute to file
@@ -1328,5 +1367,6 @@
                         !-- Check if attribute already exists
                         DO  a = 1, natt
-                           IF ( files(f)%dimensions(d)%attributes(a)%name == attribute%name )  THEN
+                           IF ( files(f)%dimensions(d)%attributes(a)%name == attribute%name ) &
+                           THEN
                               IF ( append )  THEN
                                  !-- Append existing character attribute
@@ -1385,5 +1425,6 @@
                         !-- Check if attribute already exists
                         DO  a = 1, natt
-                           IF ( files(f)%variables(d)%attributes(a)%name == attribute%name )  THEN
+                           IF ( files(f)%variables(d)%attributes(a)%name == attribute%name )  &
+                           THEN
                               IF ( append )  THEN
                                  !-- Append existing character attribute
@@ -1497,7 +1538,13 @@
       DO  f = 1, nf
 
+         !-- Skip initialization if file is already initialized
+         IF ( files(f)%is_init )  CYCLE
+
+         CALL internal_message( 'debug', routine_name // ': initialize file "' // &
+                                TRIM( files(f)%name ) // '"' )
+
          !-- Open file
          CALL open_output_file( files(f)%format, files(f)%name, files(f)%id, &
-                                files(f)%is_init, return_value=return_value )
+                                return_value=return_value )
 
          !-- Initialize file header:
@@ -1508,9 +1555,12 @@
          !-- End file definition
          IF ( return_value == 0 )  &
-            CALL dom_init_end( files(f)%format, files(f)%id, return_value=return_value )
-
-         !-- Write dimension values into file
+            CALL dom_init_end( files(f)%format, files(f)%id, files(f)%name, return_value )
+
          IF ( return_value == 0 )  THEN
 
+            !-- Flag file as initialized
+            files(f)%is_init = .TRUE.
+
+            !-- Write dimension values into file
             DO  d = 1, SIZE( files(f)%dimensions )
                IF ( ALLOCATED( files(f)%dimensions(d)%values_int8 ) )  THEN
@@ -1628,5 +1678,5 @@
    return_value = 0
 
-   !-- Set flag for files to be initialized
+   !-- Flag files which contain output variables as used
    file_is_used(:) = .FALSE.
    DO  f = 1, nf
@@ -1657,4 +1707,7 @@
    DO  f = 1, nf
 
+      !-- If a file is already initialized, it was already checked previously
+      IF ( files(f)%is_init )  CYCLE
+
       !-- Get number of defined dimensions
       ndim = SIZE( files(f)%dimensions )
@@ -1699,5 +1752,5 @@
 !> Open requested output file.
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE open_output_file( file_format, filename, file_id, is_init, return_value )
+SUBROUTINE open_output_file( file_format, filename, file_id, return_value )
 
    CHARACTER(LEN=*), INTENT(IN) ::  file_format  !< file format chosen for file
@@ -1706,31 +1759,38 @@
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'open_output_file'  !< name of routine
 
-   INTEGER(iwp), INTENT(OUT) ::  file_id       !< file ID
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-   LOGICAL, INTENT(OUT) ::  is_init  !< true if file is opened
-
+   INTEGER(iwp), INTENT(OUT) ::  file_id              !< file ID
+   INTEGER(iwp)              ::  output_return_value  !< return value of a called output routine
+   INTEGER(iwp), INTENT(OUT) ::  return_value         !< return value
+
+
+   return_value = 0
+   output_return_value = 0
 
    SELECT CASE ( TRIM( file_format ) )
 
       CASE ( 'binary' )
-         CALL binary_open_file( filename, file_id, return_value )
+         CALL binary_open_file( 'binary', filename, file_id, output_return_value )
 
       CASE ( 'netcdf4-serial' )
-         CALL netcdf4_serial_open_file( filename, file_id, return_value )
+         CALL netcdf4_open_file( 'serial', filename, file_id, output_return_value )
 
       CASE ( 'netcdf4-parallel' )
-         CALL netcdf4_parallel_open_file( filename, file_id, return_value )
+         CALL netcdf4_open_file( 'parallel', filename, file_id, output_return_value )
 
       CASE DEFAULT
          return_value = 1
-         CALL internal_message( 'error', routine_name //                              &
-                                         ': file "' // TRIM( filename ) //            &
-                                         '": file format "' // TRIM( file_format ) // &
-                                         '" not supported' )
 
    END SELECT
 
-   is_init = return_value == 0
+   IF ( output_return_value /= 0 )  THEN
+      return_value = output_return_value
+      CALL internal_message( 'error', routine_name // &
+                             ': error while opening file "' // TRIM( filename ) // '"' )
+   ELSEIF ( return_value /= 0 )  THEN
+      CALL internal_message( 'error', routine_name //                              &
+                                      ': file "' // TRIM( filename ) //            &
+                                      '": file format "' // TRIM( file_format ) // &
+                                      '" not supported' )
+   ENDIF
 
 END SUBROUTINE open_output_file
@@ -1757,6 +1817,6 @@
    IF ( ALLOCATED( file%attributes ) )  THEN
       DO  a = 1, SIZE( file%attributes )
-         return_value = write_attribute( file%format, file%id, var_id=no_var_id, &
-                                attribute=file%attributes(a) )
+         return_value = write_attribute( file%format, file%id, file%name, var_id=no_var_id, &
+                                         attribute=file%attributes(a) )
          IF ( return_value /= 0 )  EXIT
       ENDDO
@@ -1771,16 +1831,16 @@
 
             !-- Initialize non-masked dimension
-            CALL init_file_dimension( file%format,                             &
-                    file%id, file%dimensions(d)%id, file%dimensions(d)%var_id, &
-                    file%dimensions(d)%name, file%dimensions(d)%data_type,     &
-                    file%dimensions(d)%length, file%dimensions(d)%is_init, return_value )
+            CALL init_file_dimension( file%format, file%id, file%name,     &
+                    file%dimensions(d)%id, file%dimensions(d)%var_id,      &
+                    file%dimensions(d)%name, file%dimensions(d)%data_type, &
+                    file%dimensions(d)%length, return_value )
 
          ELSE
 
             !-- Initialize masked dimension
-            CALL init_file_dimension( file%format,                             &
-                    file%id, file%dimensions(d)%id, file%dimensions(d)%var_id, &
-                    file%dimensions(d)%name, file%dimensions(d)%data_type,     &
-                    file%dimensions(d)%length_mask, file%dimensions(d)%is_init, return_value )
+            CALL init_file_dimension( file%format, file%id, file%name,     &
+                    file%dimensions(d)%id, file%dimensions(d)%var_id,      &
+                    file%dimensions(d)%name, file%dimensions(d)%data_type, &
+                    file%dimensions(d)%length_mask, return_value )
 
          ENDIF
@@ -1789,5 +1849,7 @@
             !-- Write dimension attributes
             DO  a = 1, SIZE( file%dimensions(d)%attributes )
-               return_value = write_attribute( file%format, file%id, file%dimensions(d)%var_id, &
+               return_value = write_attribute( file%format, file%id, file%name, &
+                                 var_id=file%dimensions(d)%var_id,              &
+                                 var_name=file%dimensions(d)%name,              &
                                  attribute=file%dimensions(d)%attributes(a) )
                IF ( return_value /= 0 )  EXIT
@@ -1807,13 +1869,15 @@
          DO  d = 1, SIZE( file%variables )
 
-            CALL init_file_variable( file%format, file%id, file%variables(d)%id, &
-                    file%variables(d)%name, file%variables(d)%data_type,         &
-                    file%variables(d)%dimension_ids,                             &
-                    file%variables(d)%is_init, file%variables(d)%is_global, return_value )
+            CALL init_file_variable( file%format, file%id, file%name,                          &
+                    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 )
 
             IF ( return_value == 0  .AND.  ALLOCATED( file%variables(d)%attributes ) )  THEN
                !-- Write variable attribures
                DO  a = 1, SIZE( file%variables(d)%attributes )
-                  return_value = write_attribute( file%format, file%id, file%variables(d)%id, &
+                  return_value = write_attribute( file%format, file%id, file%name, &
+                                    var_id=file%variables(d)%id,                   &
+                                    var_name=file%variables(d)%name,               &
                                     attribute=file%variables(d)%attributes(a) )
                   IF ( return_value /= 0 )  EXIT
@@ -1835,17 +1899,34 @@
 !> Write attribute to file.
 !--------------------------------------------------------------------------------------------------!
-FUNCTION write_attribute( file_format, file_id, var_id, attribute ) RESULT( return_value )
+FUNCTION write_attribute( file_format, file_id, file_name, var_id, var_name, attribute ) RESULT( return_value )
 
    CHARACTER(LEN=*), INTENT(IN) ::  file_format  !< file format chosen for file
+   CHARACTER(LEN=*), INTENT(IN) ::  file_name    !< file name
+   CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  var_name     !< variable name
 
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'write_attribute'  !< file format chosen for file
 
-   INTEGER(iwp) ::  file_id       !< file ID
-   INTEGER(iwp) ::  return_value  !< return value
-   INTEGER(iwp) ::  var_id        !< variable ID
+   INTEGER(iwp), INTENT(IN) ::  file_id              !< file ID
+   INTEGER(iwp)             ::  return_value         !< return value
+   INTEGER(iwp)             ::  output_return_value  !< return value of a called output routine
+   INTEGER(iwp), INTENT(IN) ::  var_id               !< variable ID
 
    TYPE(attribute_type), INTENT(IN) ::  attribute  !< attribute to be written
 
 
+   return_value = 0
+   output_return_value = 0
+
+   !-- Prepare for possible error message
+   IF ( PRESENT( var_name ) )  THEN
+      temp_string = '(file "' // TRIM( file_name ) //      &
+                    '", variable "' // TRIM( var_name ) // &
+                    '", attribute "' // TRIM( attribute%name ) // '")'
+   ELSE
+      temp_string = '(file "' // TRIM( file_name ) // &
+                    '", attribute "' // TRIM( attribute%name ) // '")'
+   ENDIF
+
+   !-- Write attribute to file
    SELECT CASE ( TRIM( file_format ) )
 
@@ -1857,126 +1938,82 @@
                CALL binary_write_attribute( file_id=file_id, var_id=var_id,          &
                        att_name=attribute%name, att_value_char=attribute%value_char, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'int8' )
                CALL binary_write_attribute( file_id=file_id, var_id=var_id,          &
                        att_name=attribute%name, att_value_int8=attribute%value_int8, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'int16' )
                CALL binary_write_attribute( file_id=file_id, var_id=var_id,            &
                        att_name=attribute%name, att_value_int16=attribute%value_int16, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'int32' )
                CALL binary_write_attribute( file_id=file_id, var_id=var_id,            &
                        att_name=attribute%name, att_value_int32=attribute%value_int32, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'real32' )
                CALL binary_write_attribute( file_id=file_id, var_id=var_id,              &
                        att_name=attribute%name, att_value_real32=attribute%value_real32, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'real64' )
                CALL binary_write_attribute( file_id=file_id, var_id=var_id,              &
                        att_name=attribute%name, att_value_real64=attribute%value_real64, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE DEFAULT
                return_value = 1
-               CALL internal_message( 'error',                                          &
-                                      routine_name //                                   &
-                                      ': attribute "' // TRIM( attribute%name ) //      &
-                                      '": data type "'// TRIM( attribute%data_type ) // &
-                                      '" not supported for file format "binary".' )
+               CALL internal_message( 'error', routine_name //                     &
+                                      ': file format "' // TRIM( file_format ) //  &
+                                      '" does not support attribute data type "'// &
+                                      TRIM( attribute%data_type ) //               &
+                                      '" ' // TRIM( temp_string ) )
 
          END SELECT
 
-      CASE ( 'netcdf4-serial' )
+      CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
 
          SELECT CASE ( TRIM( attribute%data_type ) )
 
             CASE( 'char' )
-               CALL netcdf4_serial_write_attribute( file_id=file_id, var_id=var_id,  &
+               CALL netcdf4_write_attribute( file_id=file_id, var_id=var_id,  &
                        att_name=attribute%name, att_value_char=attribute%value_char, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'int8' )
-               CALL netcdf4_serial_write_attribute( file_id=file_id, var_id=var_id,  &
+               CALL netcdf4_write_attribute( file_id=file_id, var_id=var_id,  &
                        att_name=attribute%name, att_value_int8=attribute%value_int8, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'int16' )
-               CALL netcdf4_serial_write_attribute( file_id=file_id, var_id=var_id,    &
+               CALL netcdf4_write_attribute( file_id=file_id, var_id=var_id,    &
                        att_name=attribute%name, att_value_int16=attribute%value_int16, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'int32' )
-               CALL netcdf4_serial_write_attribute( file_id=file_id, var_id=var_id,    &
+               CALL netcdf4_write_attribute( file_id=file_id, var_id=var_id,    &
                        att_name=attribute%name, att_value_int32=attribute%value_int32, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'real32' )
-               CALL netcdf4_serial_write_attribute( file_id=file_id, var_id=var_id,      &
+               CALL netcdf4_write_attribute( file_id=file_id, var_id=var_id,      &
                        att_name=attribute%name, att_value_real32=attribute%value_real32, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE( 'real64' )
-               CALL netcdf4_serial_write_attribute( file_id=file_id, var_id=var_id,      &
+               CALL netcdf4_write_attribute( file_id=file_id, var_id=var_id,      &
                        att_name=attribute%name, att_value_real64=attribute%value_real64, &
-                       return_value=return_value )
+                       return_value=output_return_value )
 
             CASE DEFAULT
                return_value = 1
-               CALL internal_message( 'error',                                          &
-                                      routine_name //                                   &
-                                      ': attribute "' // TRIM( attribute%name ) //      &
-                                      '": data type "'// TRIM( attribute%data_type ) // &
-                                      '" not supported for file format "netcdf4-serial".' )
-
-         END SELECT
-
-      CASE ( 'netcdf4-parallel' )
-
-         SELECT CASE ( TRIM( attribute%data_type ) )
-
-            CASE( 'char' )
-               CALL netcdf4_parallel_write_attribute( file_id=file_id, var_id=var_id, &
-                       att_name=attribute%name, att_value_char=attribute%value_char,  &
-                       return_value=return_value )
-
-            CASE( 'int8' )
-               CALL netcdf4_parallel_write_attribute( file_id=file_id, var_id=var_id, &
-                       att_name=attribute%name, att_value_int8=attribute%value_int8,  &
-                       return_value=return_value )
-
-            CASE( 'int16' )
-               CALL netcdf4_parallel_write_attribute( file_id=file_id, var_id=var_id,  &
-                       att_name=attribute%name, att_value_int16=attribute%value_int16, &
-                       return_value=return_value )
-
-            CASE( 'int32' )
-               CALL netcdf4_parallel_write_attribute( file_id=file_id, var_id=var_id,  &
-                       att_name=attribute%name, att_value_int32=attribute%value_int32, &
-                       return_value=return_value )
-
-            CASE( 'real32' )
-               CALL netcdf4_parallel_write_attribute( file_id=file_id, var_id=var_id,    &
-                       att_name=attribute%name, att_value_real32=attribute%value_real32, &
-                       return_value=return_value )
-
-            CASE( 'real64' )
-               CALL netcdf4_parallel_write_attribute( file_id=file_id, var_id=var_id,    &
-                       att_name=attribute%name, att_value_real64=attribute%value_real64, &
-                       return_value=return_value )
-
-            CASE DEFAULT
-               return_value = 1
-               CALL internal_message( 'error',                                          &
-                                      routine_name //                                   &
-                                      ': attribute "' // TRIM( attribute%name ) //      &
-                                      '": data type "'// TRIM( attribute%data_type ) // &
-                                      '" not supported for file format "netcdf4-parallel".' )
+               CALL internal_message( 'error', routine_name //                     &
+                                      ': file format "' // TRIM( file_format ) //  &
+                                      '" does not support attribute data type "'// &
+                                      TRIM( attribute%data_type ) //               &
+                                      '" ' // TRIM( temp_string ) )
 
          END SELECT
@@ -1986,7 +2023,15 @@
          CALL internal_message( 'error',        &
                                 routine_name // &
-                                ': unsupported file format "' // TRIM( file_format ) // '"' )
+                                ': unsupported file format "' // TRIM( file_format ) // &
+                                '" ' // TRIM( temp_string ) )
 
    END SELECT
+   
+   IF ( output_return_value /= 0 )  THEN
+      return_value = output_return_value
+      CALL internal_message( 'error',        &
+                             routine_name // &
+                             ': error while writing attribute ' // TRIM( temp_string ) )
+   ENDIF
 
 END FUNCTION write_attribute
@@ -1997,45 +2042,55 @@
 !> Initialize dimension in file.
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE init_file_dimension( file_format, file_id, dim_id, var_id,        &
-                                dim_name, dim_type, dim_length, is_init, return_value )
+SUBROUTINE init_file_dimension( file_format, file_id, file_name, dim_id, var_id, &
+                                dim_name, dim_type, dim_length, return_value )
 
    CHARACTER(LEN=*), INTENT(IN) ::  dim_name     !< name of dimension
    CHARACTER(LEN=*), INTENT(IN) ::  dim_type     !< data type of dimension
    CHARACTER(LEN=*), INTENT(IN) ::  file_format  !< file format chosen for file
+   CHARACTER(LEN=*), INTENT(IN) ::  file_name    !< name of file
 
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'init_file_dimension'  !< file format chosen for file
 
-   INTEGER(iwp), INTENT(OUT) ::  dim_id        !< dimension ID
-   INTEGER(iwp), INTENT(IN)  ::  dim_length    !< length of dimension
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(OUT) ::  var_id        !< associated variable ID
-
-   LOGICAL, INTENT(OUT) ::  is_init  !< true if dimension is initialized
-
+   INTEGER(iwp), INTENT(OUT) ::  dim_id               !< dimension ID
+   INTEGER(iwp), INTENT(IN)  ::  dim_length           !< length of dimension
+   INTEGER(iwp), INTENT(IN)  ::  file_id              !< file ID
+   INTEGER(iwp)              ::  output_return_value  !< return value of a called output routine
+   INTEGER(iwp), INTENT(OUT) ::  return_value         !< return value
+   INTEGER(iwp), INTENT(OUT) ::  var_id               !< associated variable ID
+
+
+   return_value = 0
+   output_return_value = 0
+
+   temp_string = '(file "' // TRIM( file_name ) // &
+                 '", dimension "' // TRIM( dim_name ) // '")'
 
    SELECT CASE ( TRIM( file_format ) )
 
       CASE ( 'binary' )
-         CALL binary_init_dimension( file_id, dim_id, var_id, &
-                 dim_name, dim_type, dim_length, is_init, return_value )
+         CALL binary_init_dimension( 'binary', file_id, dim_id, var_id, &
+                 dim_name, dim_type, dim_length, return_value=output_return_value )
 
       CASE ( 'netcdf4-serial' )
-         CALL netcdf4_serial_init_dimension( file_id, dim_id, var_id, &
-                 dim_name, dim_type, dim_length, is_init, return_value )
+         CALL netcdf4_init_dimension( 'serial', file_id, dim_id, var_id, &
+                 dim_name, dim_type, dim_length, return_value=output_return_value )
 
       CASE ( 'netcdf4-parallel' )
-         CALL netcdf4_parallel_init_dimension( file_id, dim_id, var_id, &
-                 dim_name, dim_type, dim_length, is_init, return_value )
+         CALL netcdf4_init_dimension( 'parallel', file_id, dim_id, var_id, &
+                 dim_name, dim_type, dim_length, return_value=output_return_value )
 
       CASE DEFAULT
          return_value = 1
-         WRITE( temp_string, * ) file_id
-         CALL internal_message( 'error', routine_name //                              &
-                                         ': file id = ' // TRIM( temp_string ) //     &
-                                         '": file format "' // TRIM( file_format ) // &
-                                         '" not supported' )
+         CALL internal_message( 'error', routine_name //                    &
+                                ': file format "' // TRIM( file_format ) // &
+                                '" not supported ' // TRIM( temp_string ) )
 
    END SELECT
+
+   IF ( output_return_value /= 0 )  THEN
+      return_value = output_return_value
+      CALL internal_message( 'error', routine_name // &
+                             ': error while defining dimension ' // TRIM( temp_string ) )
+   ENDIF
 
 END SUBROUTINE init_file_dimension
@@ -2097,9 +2152,10 @@
 !> Initialize variable.
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE init_file_variable( file_format, file_id, var_id,   &
-                               var_name, var_type, var_dim_id, &
-                               is_init, is_global, return_value )
+SUBROUTINE init_file_variable( file_format, file_id, file_name,        &
+                               var_id, var_name, var_type, var_dim_id, &
+                               is_global, return_value )
 
    CHARACTER(LEN=*), INTENT(IN) ::  file_format  !< file format chosen for file
+   CHARACTER(LEN=*), INTENT(IN) ::  file_name    !< file name
    CHARACTER(LEN=*), INTENT(IN) ::  var_name     !< name of variable
    CHARACTER(LEN=*), INTENT(IN) ::  var_type     !< data type of variable
@@ -2107,35 +2163,47 @@
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'init_file_variable'  !< file format chosen for file
 
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(OUT) ::  var_id        !< variable ID
+   INTEGER(iwp), INTENT(IN)  ::  file_id              !< file ID
+   INTEGER(iwp)              ::  output_return_value  !< return value of a called output routine
+   INTEGER(iwp), INTENT(OUT) ::  return_value         !< return value
+   INTEGER(iwp), INTENT(OUT) ::  var_id               !< variable ID
 
    INTEGER(iwp), DIMENSION(:), INTENT(IN) ::  var_dim_id  !< list of dimension IDs used by variable
 
    LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global
-   LOGICAL, INTENT(OUT) ::  is_init    !< true if variable is initialized
-
+
+
+   return_value = 0
+   output_return_value = 0
+
+   temp_string = '(file "' // TRIM( file_name ) // &
+                 '", variable "' // TRIM( var_name ) // '")'
 
    SELECT CASE ( TRIM( file_format ) )
 
       CASE ( 'binary' )
-         CALL binary_init_variable( file_id, var_id, var_name, var_type, var_dim_id, &
-                                    is_init, is_global, return_value )
+         CALL binary_init_variable( 'binary', file_id, var_id, var_name, var_type, &
+                                    var_dim_id, is_global, return_value=output_return_value )
 
       CASE ( 'netcdf4-serial' )
-         CALL netcdf4_serial_init_variable( file_id, var_id, var_name, var_type, var_dim_id, &
-                                            is_init, is_global, return_value )
+         CALL netcdf4_init_variable( 'serial', file_id, var_id, var_name, var_type, &
+                                     var_dim_id, is_global, return_value=output_return_value )
 
       CASE ( 'netcdf4-parallel' )
-         CALL netcdf4_parallel_init_variable( file_id, var_id, var_name, var_type, var_dim_id, &
-                                              is_init, is_global, return_value )
+         CALL netcdf4_init_variable( 'parallel', file_id, var_id, var_name, var_type, &
+                                     var_dim_id, is_global, return_value=output_return_value )
 
       CASE DEFAULT
          return_value = 1
-         is_init = .FALSE.
-         CALL internal_message( 'error', routine_name // &
-                                ': unsupported file format "' // TRIM( file_format ) )
+         CALL internal_message( 'error', routine_name //                    &
+                                ': file format "' // TRIM( file_format ) // &
+                                '" not supported ' // TRIM( temp_string ) )
 
    END SELECT
+
+   IF ( output_return_value /= 0 )  THEN
+      return_value = output_return_value
+      CALL internal_message( 'error', routine_name // &
+                             ': error while defining variable ' // TRIM( temp_string ) )
+   ENDIF
 
 END SUBROUTINE init_file_variable
@@ -2148,34 +2216,43 @@
 !> @todo Do we need an MPI barrier at the end?
 !--------------------------------------------------------------------------------------------------!
-SUBROUTINE dom_init_end( file_format, file_id, return_value )
+SUBROUTINE dom_init_end( file_format, file_id, file_name, return_value )
 
    CHARACTER(LEN=*), INTENT(IN) ::  file_format  !< file format
+   CHARACTER(LEN=*), INTENT(IN) ::  file_name    !< file name
 
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'dom_init_end'  !< name of routine
 
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file id
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
+   INTEGER(iwp), INTENT(IN)  ::  file_id              !< file id
+   INTEGER(iwp)              ::  output_return_value  !< return value of a called output routine
+   INTEGER(iwp), INTENT(OUT) ::  return_value         !< return value
+
+
+   return_value = 0
+   output_return_value = 0
+
+   temp_string = '(file "' // TRIM( file_name ) // '")'
 
    SELECT CASE ( TRIM( file_format ) )
 
       CASE ( 'binary' )
-         CALL binary_init_end( file_id, return_value )
-
-      CASE ( 'netcdf4-serial' )
-         CALL netcdf4_serial_init_end( file_id, return_value )
-
-      CASE ( 'netcdf4-parallel' )
-         CALL netcdf4_parallel_init_end( file_id, return_value )
+         CALL binary_init_end( file_id, output_return_value )
+
+      CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
+         CALL netcdf4_init_end( file_id, output_return_value )
 
       CASE DEFAULT
          return_value = 1
-         WRITE( temp_string, * ) file_id
-         CALL internal_message( 'error', routine_name //                             &
-                                         ': file id = ' // TRIM( temp_string ) //    &
-                                         ': file format "' // TRIM( file_format ) // &
-                                         '" not supported' )
+         CALL internal_message( 'error', routine_name //                    &
+                                ': file format "' // TRIM( file_format ) // &
+                                '" not supported ' // TRIM( temp_string ) )
 
    END SELECT
+
+   IF ( output_return_value /= 0 )  THEN
+      return_value = output_return_value
+      CALL internal_message( 'error', routine_name // &
+                             ': error while leaving file-definition state ' // &
+                             TRIM( temp_string ) )
+   ENDIF
 
    ! CALL MPI_Barrier( MPI_COMM_WORLD, return_value )
@@ -2211,17 +2288,18 @@
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'dom_write_var'  !< name of routine
 
-   INTEGER(iwp) ::  d             !< loop index
-   INTEGER(iwp) ::  file_id       !< file ID
-   INTEGER(iwp) ::  i             !< loop index
-   INTEGER(iwp) ::  j             !< loop index
-   INTEGER(iwp) ::  k             !< loop index
-   INTEGER(iwp) ::  return_value  !< return value
-   INTEGER(iwp) ::  var_id        !< variable ID
+   INTEGER(iwp) ::  d                    !< loop index
+   INTEGER(iwp) ::  file_id              !< file ID
+   INTEGER(iwp) ::  i                    !< loop index
+   INTEGER(iwp) ::  j                    !< loop index
+   INTEGER(iwp) ::  k                    !< loop index
+   INTEGER(iwp) ::  output_return_value  !< return value of a called output routine
+   INTEGER(iwp) ::  return_value         !< return value
+   INTEGER(iwp) ::  var_id               !< variable ID
 
    INTEGER(iwp), DIMENSION(:),   INTENT(IN)  ::  bounds_end        !< end index (upper bound) of variable at each dimension
    INTEGER(iwp), DIMENSION(:),   INTENT(IN)  ::  bounds_start      !< start index (lower bound) of variable at each dimension
    INTEGER(iwp), DIMENSION(:),   ALLOCATABLE ::  bounds_dim_start  !< start index (lower bound) of each dimension of variable
-   INTEGER(iwp), DIMENSION(:),   ALLOCATABLE ::  bounds_end_new    !< start index (upper bound) of masked variable at each dimension
-   INTEGER(iwp), DIMENSION(:),   ALLOCATABLE ::  bounds_start_new  !< start index (lower bound) of masked variable at each dimension
+   INTEGER(iwp), DIMENSION(:),   ALLOCATABLE ::  bounds_end_new    !< start index (upper bound) of msked var at each dim
+   INTEGER(iwp), DIMENSION(:),   ALLOCATABLE ::  bounds_start_new  !< start index (lower bound) of msked var at each dim
    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  masked_indices    !< dummy list holding all masked indices along a dimension
 
@@ -2330,4 +2408,7 @@
 
 
+   return_value = 0
+   output_return_value = 0
+
    CALL internal_message( 'debug', routine_name // ': write ' // TRIM( name ) // &
                                    ' into file ' // TRIM( filename ) )
@@ -2343,8 +2424,8 @@
            SIZE( bounds_end ) /= SIZE( dimension_list ) )  THEN
          return_value = 1
-         CALL internal_message( 'error', routine_name //                      &
-                                         ': variable "' // TRIM( name ) //    &
-                                         '" in file "' // TRIM( filename ) // &
-                                         '": given bounds do not match with number of dimensions' )
+         CALL internal_message( 'error', routine_name //             &
+                                ': variable "' // TRIM( name ) //    &
+                                '" in file "' // TRIM( filename ) // &
+                                '": given bounds do not match with number of dimensions' )
       ENDIF
 
@@ -2819,384 +2900,255 @@
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_0d=var_int8_0d_pointer, return_value=return_value )
+                       var_int8_0d=var_int8_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int8_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_1d=var_int8_1d_pointer, return_value=return_value )
+                       var_int8_1d=var_int8_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int8_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_2d=var_int8_2d_pointer, return_value=return_value )
+                       var_int8_2d=var_int8_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int8_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_3d=var_int8_3d_pointer, return_value=return_value )
+                       var_int8_3d=var_int8_3d_pointer, return_value=output_return_value )
             !-- 16bit integer output
             ELSEIF ( PRESENT( var_int16_0d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_0d=var_int16_0d_pointer, return_value=return_value )
+                       var_int16_0d=var_int16_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int16_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_1d=var_int16_1d_pointer, return_value=return_value )
+                       var_int16_1d=var_int16_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int16_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_2d=var_int16_2d_pointer, return_value=return_value )
+                       var_int16_2d=var_int16_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int16_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_3d=var_int16_3d_pointer, return_value=return_value )
+                       var_int16_3d=var_int16_3d_pointer, return_value=output_return_value )
             !-- 32bit integer output
             ELSEIF ( PRESENT( var_int32_0d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_0d=var_int32_0d_pointer, return_value=return_value )
+                       var_int32_0d=var_int32_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int32_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_1d=var_int32_1d_pointer, return_value=return_value )
+                       var_int32_1d=var_int32_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int32_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_2d=var_int32_2d_pointer, return_value=return_value )
+                       var_int32_2d=var_int32_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int32_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_3d=var_int32_3d_pointer, return_value=return_value )
+                       var_int32_3d=var_int32_3d_pointer, return_value=output_return_value )
             !-- working-precision integer output
             ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_0d=var_intwp_0d_pointer, return_value=return_value )
+                       var_intwp_0d=var_intwp_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_1d=var_intwp_1d_pointer, return_value=return_value )
+                       var_intwp_1d=var_intwp_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_2d=var_intwp_2d_pointer, return_value=return_value )
+                       var_intwp_2d=var_intwp_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_3d=var_intwp_3d_pointer, return_value=return_value )
+                       var_intwp_3d=var_intwp_3d_pointer, return_value=output_return_value )
             !-- 32bit real output
             ELSEIF ( PRESENT( var_real32_0d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_0d=var_real32_0d_pointer, return_value=return_value )
+                       var_real32_0d=var_real32_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real32_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_1d=var_real32_1d_pointer, return_value=return_value )
+                       var_real32_1d=var_real32_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real32_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_2d=var_real32_2d_pointer, return_value=return_value )
+                       var_real32_2d=var_real32_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real32_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_3d=var_real32_3d_pointer, return_value=return_value )
+                       var_real32_3d=var_real32_3d_pointer, return_value=output_return_value )
             !-- 64bit real output
             ELSEIF ( PRESENT( var_real64_0d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_0d=var_real64_0d_pointer, return_value=return_value )
+                       var_real64_0d=var_real64_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real64_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_1d=var_real64_1d_pointer, return_value=return_value )
+                       var_real64_1d=var_real64_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real64_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_2d=var_real64_2d_pointer, return_value=return_value )
+                       var_real64_2d=var_real64_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real64_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_3d=var_real64_3d_pointer, return_value=return_value )
+                       var_real64_3d=var_real64_3d_pointer, return_value=output_return_value )
             !-- working-precision real output
             ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_0d=var_realwp_0d_pointer, return_value=return_value )
+                       var_realwp_0d=var_realwp_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_1d=var_realwp_1d_pointer, return_value=return_value )
+                       var_realwp_1d=var_realwp_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_2d=var_realwp_2d_pointer, return_value=return_value )
+                       var_realwp_2d=var_realwp_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
                CALL binary_write_variable( file_id, var_id,                                      &
                        bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_3d=var_realwp_3d_pointer, return_value=return_value )
+                       var_realwp_3d=var_realwp_3d_pointer, return_value=output_return_value )
             ELSE
                return_value = 1
-               CALL internal_message( 'error', routine_name //                                    &
-                                               ': variable "' // TRIM( name ) //                  &
-                                               '" in file "' // TRIM( filename ) //               &
-                                               '": output_type not supported by file format "' // &
-                                               TRIM( file_format ) // '"' )
+               CALL internal_message( 'error', routine_name //                           &
+                                      ': variable "' // TRIM( name ) //                  &
+                                      '" in file "' // TRIM( filename ) //               &
+                                      '": output_type not supported by file format "' // &
+                                      TRIM( file_format ) // '"' )
             ENDIF
 
-         CASE ( 'netcdf4-serial' )
+         CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
             !-- 8bit integer output
             IF ( PRESENT( var_int8_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_0d=var_int8_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int8_0d=var_int8_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int8_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_1d=var_int8_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int8_1d=var_int8_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int8_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_2d=var_int8_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int8_2d=var_int8_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int8_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_3d=var_int8_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int8_3d=var_int8_3d_pointer, return_value=output_return_value )
             !-- 16bit integer output
             ELSEIF ( PRESENT( var_int16_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_0d=var_int16_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int16_0d=var_int16_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int16_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_1d=var_int16_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int16_1d=var_int16_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int16_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_2d=var_int16_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int16_2d=var_int16_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int16_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_3d=var_int16_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int16_3d=var_int16_3d_pointer, return_value=output_return_value )
             !-- 32bit integer output
             ELSEIF ( PRESENT( var_int32_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_0d=var_int32_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int32_0d=var_int32_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int32_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_1d=var_int32_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int32_1d=var_int32_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int32_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_2d=var_int32_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int32_2d=var_int32_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_int32_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_3d=var_int32_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_int32_3d=var_int32_3d_pointer, return_value=output_return_value )
             !-- working-precision integer output
             ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_0d=var_intwp_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_intwp_0d=var_intwp_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_1d=var_intwp_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_intwp_1d=var_intwp_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_2d=var_intwp_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_intwp_2d=var_intwp_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_3d=var_intwp_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_intwp_3d=var_intwp_3d_pointer, return_value=output_return_value )
             !-- 32bit real output
             ELSEIF ( PRESENT( var_real32_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_0d=var_real32_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real32_0d=var_real32_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real32_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_1d=var_real32_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real32_1d=var_real32_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real32_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_2d=var_real32_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real32_2d=var_real32_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real32_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_3d=var_real32_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real32_3d=var_real32_3d_pointer, return_value=output_return_value )
             !-- 64bit real output
             ELSEIF ( PRESENT( var_real64_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_0d=var_real64_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real64_0d=var_real64_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real64_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_1d=var_real64_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real64_1d=var_real64_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real64_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_2d=var_real64_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real64_2d=var_real64_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_real64_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_3d=var_real64_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_real64_3d=var_real64_3d_pointer, return_value=output_return_value )
             !-- working-precision real output
             ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_0d=var_realwp_0d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_realwp_0d=var_realwp_0d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_1d=var_realwp_1d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_realwp_1d=var_realwp_1d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_2d=var_realwp_2d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_realwp_2d=var_realwp_2d_pointer, return_value=output_return_value )
             ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
-               CALL netcdf4_serial_write_variable( file_id, var_id,                              &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_3d=var_realwp_3d_pointer, return_value=return_value )
+               CALL netcdf4_write_variable( file_id, var_id,                              &
+                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
+                       var_realwp_3d=var_realwp_3d_pointer, return_value=output_return_value )
             ELSE
                return_value = 1
-               CALL internal_message( 'error', routine_name //                                    &
-                                               ': variable "' // TRIM( name ) //                  &
-                                               '" in file "' // TRIM( filename ) //               &
-                                               '": output_type not supported by file format "' // &
-                                               TRIM( file_format ) // '"' )
-            ENDIF
-
-         CASE ( 'netcdf4-parallel' )
-            !-- 8bit integer output
-            IF ( PRESENT( var_int8_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_0d=var_int8_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int8_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_1d=var_int8_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int8_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_2d=var_int8_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int8_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int8_3d=var_int8_3d_pointer, return_value=return_value )
-            !-- 16bit integer output
-            ELSEIF ( PRESENT( var_int16_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_0d=var_int16_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int16_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_1d=var_int16_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int16_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_2d=var_int16_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int16_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int16_3d=var_int16_3d_pointer, return_value=return_value )
-            !-- 32bit integer output
-            ELSEIF ( PRESENT( var_int32_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_0d=var_int32_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int32_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_1d=var_int32_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int32_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_2d=var_int32_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_int32_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_int32_3d=var_int32_3d_pointer, return_value=return_value )
-            !-- working-precision integer output
-            ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_0d=var_intwp_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_1d=var_intwp_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_2d=var_intwp_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_intwp_3d=var_intwp_3d_pointer, return_value=return_value )
-            !-- 32bit real output
-            ELSEIF ( PRESENT( var_real32_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_0d=var_real32_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_real32_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_1d=var_real32_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_real32_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_2d=var_real32_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_real32_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real32_3d=var_real32_3d_pointer, return_value=return_value )
-            !-- 64bit real output
-            ELSEIF ( PRESENT( var_real64_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_0d=var_real64_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_real64_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_1d=var_real64_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_real64_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_2d=var_real64_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_real64_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_real64_3d=var_real64_3d_pointer, return_value=return_value )
-            !-- working-precision real output
-            ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_0d=var_realwp_0d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_1d=var_realwp_1d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_2d=var_realwp_2d_pointer, return_value=return_value )
-            ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
-               CALL netcdf4_parallel_write_variable( file_id, var_id,                            &
-                       bounds_start_new, bounds_end_new, bounds_dim_start, do_output, is_global, &
-                       var_realwp_3d=var_realwp_3d_pointer, return_value=return_value )
-            ELSE
-               return_value = 1
-               CALL internal_message( 'error', routine_name //                                    &
-                                               ': variable "' // TRIM( name ) //                  &
-                                               '" in file "' // TRIM( filename ) //               &
-                                               '": output_type not supported by file format "' // &
-                                               TRIM( file_format ) // '"' )
+               CALL internal_message( 'error', routine_name //                           &
+                                      ': variable "' // TRIM( name ) //                  &
+                                      '" in file "' // TRIM( filename ) //               &
+                                      '": output_type not supported by file format "' // &
+                                      TRIM( file_format ) // '"' )
             ENDIF
 
@@ -3210,4 +3162,11 @@
       END SELECT
 
+      IF ( return_value == 0  .AND.  output_return_value /= 0 )  THEN
+         return_value = 1
+         CALL internal_message( 'error', routine_name //                              &
+                                ': error while writing variable "' // TRIM( name ) // &
+                                '" in file "' // TRIM( filename ) // '"' )
+      ENDIF
+
    ENDIF
 
@@ -3248,4 +3207,15 @@
    DO  f = 1, nf
       IF ( TRIM( filename ) == TRIM( files(f)%name ) )  THEN
+         
+         IF ( .NOT. files(f)%is_init )  THEN
+            return_value = 1
+            CALL internal_message( 'error', routine_name //                    &
+                                   ': file "' // TRIM( filename ) //           &
+                                   '" is not initialized. ' //                 &
+                                   'Writing variable "' // TRIM( var_name ) // &
+                                   '" to file is impossible.' )
+            EXIT
+         ENDIF
+         
          file_id     = files(f)%id
          file_format = files(f)%format
@@ -3421,5 +3391,6 @@
 
    INTEGER(iwp) ::  return_value           !< return value
-   INTEGER(iwp) ::  return_value_internal  !< return value from called routines
+   INTEGER(iwp) ::  return_value_internal  !< error code after closing a single file
+   INTEGER(iwp) ::  output_return_value    !< return value from called routines
    INTEGER(iwp) ::  f                      !< loop index
 
@@ -3429,25 +3400,35 @@
    DO  f = 1, nf
 
-      return_value_internal = 0
-
-      SELECT CASE ( TRIM( files(f)%format ) )
-
-         CASE ( 'binary' )
-            CALL binary_finalize( files(f)%id, return_value_internal )
-
-         CASE ( 'netcdf4-serial' )
-            CALL netcdf4_serial_finalize( files(f)%id, return_value_internal )
-
-         CASE ( 'netcdf4-parallel' )
-            CALL netcdf4_parallel_finalize( files(f)%id, return_value_internal )
-
-         CASE DEFAULT
-            return_value_internal = 1
-            CALL internal_message( 'error', routine_name // &
-                                   ': unsupported file format "' // TRIM( files(f)%format ) )
-
-      END SELECT
-
-      IF ( return_value_internal /= 0 )  return_value = return_value_internal
+      IF ( files(f)%is_init )  THEN
+
+         output_return_value = 0
+         return_value_internal = 0
+
+         SELECT CASE ( TRIM( files(f)%format ) )
+
+            CASE ( 'binary' )
+               CALL binary_finalize( files(f)%id, output_return_value )
+
+            CASE ( 'netcdf4-parallel', 'netcdf4-serial' )
+               CALL netcdf4_finalize( files(f)%id, output_return_value )
+
+            CASE DEFAULT
+               return_value_internal = 1
+
+         END SELECT
+
+         IF ( output_return_value /= 0 )  THEN
+            return_value = output_return_value
+            CALL internal_message( 'error', routine_name //             &
+                                   ': error while finalizing file "' // &
+                                   TRIM( files(f)%name ) // '"' )
+         ELSEIF ( return_value_internal /= 0 )  THEN
+            return_value = return_value_internal
+            CALL internal_message( 'error', routine_name //         &
+                                   ': unsupported file format "' // &
+                                   TRIM( files(f)%format ) // '"' )
+         ENDIF
+
+      ENDIF
 
    ENDDO
@@ -3488,15 +3469,12 @@
 
    CHARACTER(LEN=800), INTENT(OUT) ::  error_message         !< return error message to main program
-   CHARACTER(LEN=800)              ::  module_error_message  !< error message created by other module
-
-
-   CALL binary_get_error_message( module_error_message )
-   internal_error_message = TRIM( internal_error_message ) // module_error_message
-
-   CALL netcdf4_serial_get_error_message( module_error_message )
-   internal_error_message = TRIM( internal_error_message ) // module_error_message
-
-   CALL netcdf4_parallel_get_error_message( module_error_message )
-   internal_error_message = TRIM( internal_error_message ) // module_error_message
+   CHARACTER(LEN=800)              ::  output_error_message  !< error message created by other module
+
+
+   CALL binary_get_error_message( output_error_message )
+   internal_error_message = TRIM( internal_error_message ) // output_error_message
+
+   CALL netcdf4_get_error_message( output_error_message )
+   internal_error_message = TRIM( internal_error_message ) // output_error_message
 
    error_message = internal_error_message
Index: /palm/trunk/SOURCE/data_output_netcdf4_module.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_netcdf4_module.f90	(revision 4106)
+++ /palm/trunk/SOURCE/data_output_netcdf4_module.f90	(revision 4106)
@@ -0,0 +1,853 @@
+!> @file data_output_netcdf4_module.f90
+!--------------------------------------------------------------------------------------------------!
+! This file is part of the PALM model system.
+!
+! PALM is free software: you can redistribute it and/or modify it under the
+! terms of the GNU General Public License as published by the Free Software
+! Foundation, either version 3 of the License, or (at your option) any later
+! version.
+!
+! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
+! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License along with
+! PALM. If not, see <http://www.gnu.org/licenses/>.
+!
+! Copyright 2019-2019 Leibniz Universitaet Hannover
+!--------------------------------------------------------------------------------------------------!
+!
+! Current revisions:
+! ------------------
+!
+!
+! Former revisions:
+! -----------------
+! $Id$
+! Initial revision
+!
+!
+! Authors:
+! --------
+!> @author: Tobias Gronemeier
+!
+! Description:
+! ------------
+!> 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.
+!--------------------------------------------------------------------------------------------------!
+MODULE data_output_netcdf4_module
+
+   USE kinds
+
+#if defined( __parallel )
+#if defined( __mpifh )
+   INCLUDE "mpif.h"
+#else
+   USE MPI
+#endif
+#endif
+
+#if defined( __netcdf4 )
+   USE NETCDF
+#endif
+
+   IMPLICIT NONE
+
+   CHARACTER(LEN=800) ::  internal_error_message = ''  !< string containing the last error message
+   CHARACTER(LEN=800) ::  temp_string                  !< dummy string
+
+   CHARACTER(LEN=*), PARAMETER ::  mode_parallel = 'parallel'  !< string selecting netcdf4 parallel mode
+   CHARACTER(LEN=*), PARAMETER ::  mode_serial   = 'serial'    !< string selecting netcdf4 serial mode
+
+   INTEGER(iwp) ::  debug_output_unit       !< Fortran Unit Number of the debug-output file
+   INTEGER(iwp) ::  global_id_in_file = -1  !< value of global ID within a file
+
+   LOGICAL ::  print_debug_output = .FALSE.  !< if true, debug output is printed
+
+   SAVE
+
+   PRIVATE
+
+   INTERFACE netcdf4_init_module
+      MODULE PROCEDURE netcdf4_init_module
+   END INTERFACE netcdf4_init_module
+
+   INTERFACE netcdf4_open_file
+      MODULE PROCEDURE netcdf4_open_file
+   END INTERFACE netcdf4_open_file
+
+   INTERFACE netcdf4_init_dimension
+      MODULE PROCEDURE netcdf4_init_dimension
+   END INTERFACE netcdf4_init_dimension
+
+   INTERFACE netcdf4_init_variable
+      MODULE PROCEDURE netcdf4_init_variable
+   END INTERFACE netcdf4_init_variable
+
+   INTERFACE netcdf4_write_attribute
+      MODULE PROCEDURE netcdf4_write_attribute
+   END INTERFACE netcdf4_write_attribute
+
+   INTERFACE netcdf4_init_end
+      MODULE PROCEDURE netcdf4_init_end
+   END INTERFACE netcdf4_init_end
+
+   INTERFACE netcdf4_write_variable
+      MODULE PROCEDURE netcdf4_write_variable
+   END INTERFACE netcdf4_write_variable
+
+   INTERFACE netcdf4_finalize
+      MODULE PROCEDURE netcdf4_finalize
+   END INTERFACE netcdf4_finalize
+
+   INTERFACE netcdf4_get_error_message
+      MODULE PROCEDURE netcdf4_get_error_message
+   END INTERFACE netcdf4_get_error_message
+
+   PUBLIC &
+      netcdf4_finalize, &
+      netcdf4_get_error_message, &
+      netcdf4_init_dimension, &
+      netcdf4_init_end, &
+      netcdf4_init_module, &
+      netcdf4_init_variable, &
+      netcdf4_open_file, &
+      netcdf4_write_attribute, &
+      netcdf4_write_variable
+
+
+CONTAINS
+
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize data-output module.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_init_module( program_debug_output_unit, debug_output, dom_global_id )
+
+   INTEGER(iwp), INTENT(IN) ::  dom_global_id              !< global id within a file defined by DOM
+   INTEGER(iwp), INTENT(IN) ::  program_debug_output_unit  !< file unit number for debug output
+
+   LOGICAL, INTENT(IN) ::  debug_output  !< if true, debug output is printed
+
+
+   debug_output_unit = program_debug_output_unit
+
+   print_debug_output = debug_output
+
+   global_id_in_file = dom_global_id
+
+END SUBROUTINE netcdf4_init_module
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Open netcdf file.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_open_file( mode, filename, file_id, return_value )
+
+   CHARACTER(LEN=*), INTENT(IN) ::  filename  !< name of file
+   CHARACTER(LEN=*), INTENT(IN) ::  mode      !< operation mode (either parallel or serial)
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_open_file'  !< name of this routine
+
+   INTEGER(iwp), INTENT(OUT) ::  file_id       !< file ID
+   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
+   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
+
+
+   return_value = 0
+
+   !-- Open new file
+   CALL internal_message( 'debug', routine_name // ': create file "' // TRIM( filename ) // '"' )
+
+   IF ( TRIM( mode ) == mode_serial )  THEN
+
+#if defined( __netcdf4 )
+      nc_stat = NF90_CREATE( TRIM( filename ),                    &
+                             IOR( NF90_NOCLOBBER, NF90_NETCDF4 ), &
+                             file_id )
+#else
+      file_id = -1
+      nc_stat = 0
+      return_value = 1
+      CALL internal_message( 'error', routine_name //                               &
+                             ': pre-processor directive "__netcdf4" not given. ' // &
+                             'Using NetCDF4 output not possible' )
+#endif
+
+   ELSEIF ( TRIM( mode ) == mode_parallel )  THEN
+
+#if defined( __parallel ) && defined( __netcdf4 ) && defined( __netcdf4_parallel )
+      nc_stat = NF90_CREATE( TRIM( filename ),                                       &
+                             IOR( NF90_NOCLOBBER, IOR( NF90_NETCDF4, NF90_MPIIO ) ), &
+                             file_id, COMM = MPI_COMM_WORLD, INFO = MPI_INFO_NULL )
+#else
+      file_id = -1
+      nc_stat = 0
+      return_value = 1
+      CALL internal_message( 'error', routine_name //                                 &
+                             ': pre-processor directives "__parallel" and/or ' //     &
+                             '"__netcdf4" and/or "__netcdf4_parallel" not given. ' // &
+                             'Using parallel NetCDF4 output not possible' )
+#endif
+
+   ELSE
+      file_id = -1
+      nc_stat = 0
+      return_value = 1
+      CALL internal_message( 'error', routine_name // ': selected mode "' // &
+                                      TRIM( mode ) // '" must be either "' // &
+                                      mode_serial // '" or "' // mode_parallel // '"' )
+   ENDIF
+
+#if defined( __netcdf4 )
+   IF ( nc_stat /= NF90_NOERR )  THEN
+      return_value = 1
+      CALL internal_message( 'error', routine_name // ': NetCDF error while opening file "' // &
+                                      TRIM( filename ) // '": ' // NF90_STRERROR( nc_stat ) )
+   ENDIF
+#endif
+
+END SUBROUTINE netcdf4_open_file
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Write attribute to netcdf file.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_write_attribute( file_id, var_id, att_name, att_value_char, &
+                 att_value_int8, att_value_int16, att_value_int32,             &
+                 att_value_real32, att_value_real64, return_value )
+
+   CHARACTER(LEN=*), INTENT(IN)           ::  att_name        !< name of attribute
+   CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  att_value_char  !< value of attribute
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_write_attribute'  !< name of this routine
+
+   INTEGER(iwp) ::  nc_stat    !< netcdf return value
+   INTEGER(iwp) ::  target_id  !< ID of target which gets attribute (either global or var_id)
+
+   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
+   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
+   INTEGER(iwp), INTENT(IN)  ::  var_id        !< variable ID
+
+   INTEGER(KIND=1), INTENT(IN), OPTIONAL ::  att_value_int8   !< value of attribute
+   INTEGER(KIND=2), INTENT(IN), OPTIONAL ::  att_value_int16  !< value of attribute
+   INTEGER(KIND=4), INTENT(IN), OPTIONAL ::  att_value_int32  !< value of attribute
+
+   REAL(KIND=4), INTENT(IN), OPTIONAL ::  att_value_real32  !< value of attribute
+   REAL(KIND=8), INTENT(IN), OPTIONAL ::  att_value_real64  !< value of attribute
+
+
+#if defined( __netcdf4 )
+   return_value = 0
+
+   IF ( var_id == global_id_in_file )  THEN
+      target_id = NF90_GLOBAL
+   ELSE
+      target_id = var_id
+   ENDIF
+
+   CALL internal_message( 'debug', &
+                          routine_name // ': write attribute "' // TRIM( att_name ) // '"' )
+
+   IF ( PRESENT( att_value_char ) )  THEN
+      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), TRIM( att_value_char ) )
+   ELSEIF ( PRESENT( att_value_int8 ) )  THEN
+      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int8 )
+   ELSEIF ( PRESENT( att_value_int16 ) )  THEN
+      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int16 )
+   ELSEIF ( PRESENT( att_value_int32 ) )  THEN
+      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int32 )
+   ELSEIF ( PRESENT( att_value_real32 ) )  THEN
+      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_real32 )
+   ELSEIF ( PRESENT( att_value_real64 ) )  THEN
+      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_real64 )
+   ELSE
+      return_value = 1
+      CALL internal_message( 'error', TRIM( routine_name ) // &
+                                      ': attribute "' // TRIM( att_name ) // '": no value given' )
+   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( att_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+      ENDIF
+   ENDIF
+#else
+   return_value = 1
+#endif
+
+END SUBROUTINE netcdf4_write_attribute
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize dimension.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_init_dimension( mode, file_id, dim_id, var_id, &
+              dim_name, dim_type, dim_length, return_value )
+
+   CHARACTER(LEN=*), INTENT(IN) ::  dim_name  !< name of dimension
+   CHARACTER(LEN=*), INTENT(IN) ::  dim_type  !< data type of dimension
+   CHARACTER(LEN=*), INTENT(IN) ::  mode      !< operation mode (either parallel or serial)
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_init_dimension'  !< name of this routine
+
+   INTEGER(iwp), INTENT(OUT) ::  dim_id         !< dimension ID
+   INTEGER(iwp), INTENT(IN)  ::  dim_length     !< length of dimension
+   INTEGER(iwp), INTENT(IN)  ::  file_id        !< file ID
+   INTEGER(iwp)              ::  nc_dim_length  !< length of dimension
+   INTEGER(iwp)              ::  nc_stat        !< netcdf return value
+   INTEGER(iwp), INTENT(OUT) ::  return_value   !< return value
+   INTEGER(iwp), INTENT(OUT) ::  var_id         !< variable ID
+
+
+#if defined( __netcdf4 )
+   return_value = 0
+   var_id = -1
+
+   CALL internal_message( 'debug', &
+                          routine_name // ': init dimension "' // TRIM( dim_name ) // '"' )
+
+   !-- Check if dimension is unlimited
+   IF ( dim_length < 0 )  THEN
+      nc_dim_length = NF90_UNLIMITED
+   ELSE
+      nc_dim_length = dim_length
+   ENDIF
+
+   !-- Define dimension in file
+   nc_stat = NF90_DEF_DIM( file_id, dim_name, nc_dim_length, dim_id )
+
+   IF ( nc_stat == NF90_NOERR )  THEN
+
+      !-- Define variable holding dimension values in file
+      CALL netcdf4_init_variable( mode, file_id, var_id, dim_name, dim_type, (/dim_id/), &
+                                           is_global=.TRUE., return_value=return_value )
+
+   ELSE
+      return_value = 1
+      CALL internal_message( 'error', routine_name //                                    &
+                                      ': NetCDF error while initializing dimension "' // &
+                                      TRIM( dim_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+   ENDIF
+#else
+   return_value = 1
+   var_id = -1
+   dim_id = -1
+#endif
+
+END SUBROUTINE netcdf4_init_dimension
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize variable.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_init_variable( mode, file_id, var_id, var_name, var_type, var_dim_ids, &
+                                  is_global, return_value )
+
+   CHARACTER(LEN=*), INTENT(IN) ::  mode      !< operation mode (either parallel or serial)
+   CHARACTER(LEN=*), INTENT(IN) ::  var_name  !< name of variable
+   CHARACTER(LEN=*), INTENT(IN) ::  var_type  !< data type of variable
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_init_variable'  !< name of this routine
+
+   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
+   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
+   INTEGER(iwp)              ::  nc_var_type   !< netcdf data type
+   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
+   INTEGER(iwp), INTENT(OUT) ::  var_id        !< variable ID
+
+   INTEGER(iwp), DIMENSION(:), INTENT(IN) ::  var_dim_ids  !< list of dimension IDs used by variable
+
+   LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global (same on all PE)
+
+
+#if defined( __netcdf4 )
+   return_value = 0
+
+   WRITE( temp_string, * ) is_global
+   CALL internal_message( 'debug', routine_name // ': init variable "' // TRIM( var_name ) // &
+                                   '" ( is_global = ' // TRIM( temp_string ) // ')' )
+
+   nc_var_type = get_netcdf_data_type( var_type )
+
+   IF ( nc_var_type /= -1_iwp )  THEN
+
+      !-- Define variable in file
+      nc_stat = NF90_DEF_VAR( file_id, var_name, nc_var_type, var_dim_ids, var_id )
+
+#if defined( __netcdf4_parallel )
+      !-- Define how variable can be accessed by PEs in parallel netcdf file
+      IF ( nc_stat == NF90_NOERR  .AND.  TRIM( mode ) == mode_parallel )  THEN
+         IF ( is_global )  THEN
+            nc_stat = NF90_VAR_PAR_ACCESS( file_id, var_id, NF90_INDEPENDENT )
+         ELSE
+            nc_stat = NF90_VAR_PAR_ACCESS( file_id, var_id, NF90_COLLECTIVE )
+         ENDIF
+      ENDIF
+#endif
+
+      IF ( nc_stat /= NF90_NOERR)  THEN
+         return_value = 1
+         CALL internal_message( 'error', routine_name //                                   &
+                                         ': NetCDF error while initializing variable "' // &
+                                         TRIM( var_name ) // '": ' // NF90_STRERROR( nc_stat ) )
+      ENDIF
+
+   ELSE
+      return_value = 1
+   ENDIF
+
+#else
+   return_value = 1
+   var_id = -1
+#endif
+
+END SUBROUTINE netcdf4_init_variable
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Leave file definition state.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_init_end( file_id, return_value )
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_init_end'  !< name of this routine
+
+   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
+   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
+   INTEGER(iwp)              ::  old_mode      !< previous netcdf fill mode
+   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
+
+
+#if defined( __netcdf4 )
+   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_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
+#else
+   return_value = 1
+#endif
+
+END SUBROUTINE netcdf4_init_end
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Write variable of different kind into netcdf file.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_write_variable(                                        &
+              file_id, var_id, bounds_start, bounds_end, bounds_origin,   &
+              do_output, is_global,                                       &
+              var_int8_0d,   var_int8_1d,   var_int8_2d,   var_int8_3d,   &
+              var_int16_0d,  var_int16_1d,  var_int16_2d,  var_int16_3d,  &
+              var_int32_0d,  var_int32_1d,  var_int32_2d,  var_int32_3d,  &
+              var_intwp_0d,  var_intwp_1d,  var_intwp_2d,  var_intwp_3d,  &
+              var_real32_0d, var_real32_1d, var_real32_2d, var_real32_3d, &
+              var_real64_0d, var_real64_1d, var_real64_2d, var_real64_3d, &
+              var_realwp_0d, var_realwp_1d, var_realwp_2d, var_realwp_3d, &
+              return_value )
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_write_variable'  !< name of this routine
+
+   INTEGER(iwp)              ::  d             !< loop index
+   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
+   INTEGER(iwp)              ::  myid          !< id number of processor element
+   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
+   INTEGER(iwp)              ::  ndim          !< number of dimensions of variable in file
+   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
+   INTEGER(iwp), INTENT(IN)  ::  var_id        !< variable ID
+
+   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_origin  !< starting index of each dimension
+   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_end     !< ending index of variable
+   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_start   !< starting index of variable
+   INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  dim_ids        !< IDs of dimensions of variable in file
+   INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  dim_lengths    !< length of dimensions of variable in file
+   INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  value_count    !< count of values along each dimension to be written
+
+   INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL                               ::  var_int8_0d  !< output variable
+   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int8_1d  !< output variable
+   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int8_2d  !< output variable
+   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int8_3d  !< output variable
+
+   INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL                               ::  var_int16_0d  !< output variable
+   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int16_1d  !< output variable
+   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int16_2d  !< output variable
+   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int16_3d  !< output variable
+
+   INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL                               ::  var_int32_0d  !< output variable
+   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int32_1d  !< output variable
+   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int32_2d  !< output variable
+   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int32_3d  !< output variable
+
+   INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL                               ::  var_intwp_0d  !< output variable
+   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_intwp_1d  !< output variable
+   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_intwp_2d  !< output variable
+   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_intwp_3d  !< output variable
+
+   LOGICAL, INTENT(IN) ::  do_output  !< if false, set count to 0 and do no output
+   LOGICAL, INTENT(IN) ::  is_global  !< true if variable is global (same on all PE)
+
+   REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL                               ::  var_real32_0d  !< output variable
+   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_real32_1d  !< output variable
+   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_real32_2d  !< output variable
+   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_real32_3d  !< output variable
+
+   REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL                               ::  var_real64_0d  !< output variable
+   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_real64_1d  !< output variable
+   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_real64_2d  !< output variable
+   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_real64_3d  !< output variable
+
+   REAL(wp), POINTER, INTENT(IN), OPTIONAL                               ::  var_realwp_0d  !< output variable
+   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_realwp_1d  !< output variable
+   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_realwp_2d  !< output variable
+   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_realwp_3d  !< output variable
+
+
+#if defined( __netcdf4 )
+
+#if defined( __parallel )
+   CALL MPI_COMM_RANK( MPI_COMM_WORLD, myid, return_value )
+   IF ( return_value /= 0 )  THEN
+      CALL internal_message( 'error', routine_name // ': MPI_COMM_RANK error' )
+   ENDIF
+#else
+   myid = 0
+   return_value = 0
+#endif
+
+   IF ( return_value == 0  .AND.  ( .NOT. is_global  .OR.  myid == 0 ) )  THEN
+
+      WRITE( temp_string, * ) var_id
+      CALL internal_message( 'debug', routine_name // ': write variable ' // TRIM( temp_string ) )
+
+      ndim = SIZE( bounds_start )
+
+      ALLOCATE( value_count(ndim) )
+
+      IF ( do_output ) THEN
+         value_count = bounds_end - bounds_start + 1
+      ELSE
+         value_count = 0
+      END IF
+
+      !-- 8bit integer output
+      IF ( PRESENT( var_int8_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int8_0d /),       &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int8_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_1d,             &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int8_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_2d,             &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int8_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_3d,             &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      !-- 16bit integer output
+      ELSEIF ( PRESENT( var_int16_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int16_0d /),      &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int16_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_1d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int16_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_2d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int16_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_3d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      !-- 32bit integer output
+      ELSEIF ( PRESENT( var_int32_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int32_0d /),      &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int32_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_1d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int32_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_2d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_int32_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_3d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      !-- working-precision integer output
+      ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_intwp_0d /),      &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_1d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_2d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_3d,            &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      !-- 32bit real output
+      ELSEIF ( PRESENT( var_real32_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_real32_0d /),     &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_real32_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_1d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_real32_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_2d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_real32_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_3d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      !-- 64bit real output
+      ELSEIF ( PRESENT( var_real64_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_real64_0d /),     &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_real64_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_1d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_real64_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_2d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_real64_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_3d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      !-- working-precision real output
+      ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_realwp_0d /),     &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_1d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_2d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
+         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_3d,           &
+                                 start = bounds_start - bounds_origin + 1, &
+                                 count = value_count )
+      ELSE
+         return_value = 1
+         nc_stat = NF90_NOERR
+         WRITE( temp_string, '(": variable_id=",I6,", file_id=",I6)' ) var_id, file_id
+         CALL internal_message( 'error', routine_name // &
+                                TRIM( temp_string ) //   &
+                                ': no output values given' )
+      ENDIF
+
+      !-- Check for errors
+      IF ( nc_stat /= NF90_NOERR )  THEN
+         return_value = 1
+
+         IF ( nc_stat == NF90_EEDGE .OR. nc_stat == NF90_EINVALCOORDS )  THEN
+
+            !-- If given bounds exceed dimension bounds, get information of bounds in file
+            WRITE( temp_string, * )  NF90_STRERROR( nc_stat )
+
+            ALLOCATE( dim_ids(ndim) )
+            ALLOCATE( dim_lengths(ndim) )
+
+            nc_stat = NF90_INQUIRE_VARIABLE( file_id, var_id, dimids=dim_ids )
+
+            d = 1
+            DO WHILE ( d <= ndim .AND. nc_stat == NF90_NOERR )
+               nc_stat = NF90_INQUIRE_DIMENSION( file_id, dim_ids(d), len=dim_lengths(d) )
+               d = d + 1
+            ENDDO
+
+            IF ( nc_stat == NF90_NOERR )  THEN
+               WRITE( temp_string, * )  TRIM( temp_string ) // '; given variable bounds: ' //  &
+                  'start=', bounds_start, ', end=', bounds_end, '; file dimension bounds: ' // &
+                  'start=', bounds_origin, ', end=', bounds_origin + dim_lengths - 1
+               CALL internal_message( 'error', routine_name //     &
+                                      ': error while writing: ' // &
+                                      TRIM( temp_string ) )
+            ELSE
+               !-- Error occured during NF90_INQUIRE_VARIABLE or NF90_INQUIRE_DIMENSION
+               CALL internal_message( 'error', routine_name //            &
+                                      ': error while accessing file: ' // &
+                                      NF90_STRERROR( nc_stat ) )
+            ENDIF
+
+         ELSE
+            !-- Other NetCDF error
+            CALL internal_message( 'error', routine_name //     &
+                                   ': error while writing: ' // &
+                                   NF90_STRERROR( nc_stat ) )
+         ENDIF
+      ENDIF
+
+   ENDIF
+#else
+   return_value = 1
+#endif
+
+END SUBROUTINE netcdf4_write_variable
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Close netcdf file.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_finalize( file_id, return_value )
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_finalize'  !< name of routine
+
+   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
+   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
+   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
+
+
+#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 ) )
+   ENDIF
+#else
+   return_value = 1
+#endif
+
+END SUBROUTINE netcdf4_finalize
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Convert data_type string into netcdf data type value.
+!--------------------------------------------------------------------------------------------------!
+FUNCTION get_netcdf_data_type( data_type ) RESULT( return_value )
+
+   CHARACTER(LEN=*), INTENT(IN) ::  data_type  !< requested data type
+
+   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'get_netcdf_data_type'  !< name of this routine
+
+   INTEGER(iwp) ::  return_value  !< netcdf data type
+
+
+   SELECT CASE ( TRIM( data_type ) )
+
+#if defined( __netcdf4 )
+      CASE ( 'char' )
+         return_value = NF90_CHAR
+
+      CASE ( 'int8' )
+         return_value = NF90_BYTE
+
+      CASE ( 'int16' )
+         return_value = NF90_SHORT
+
+      CASE ( 'int32' )
+         return_value = NF90_INT
+
+      CASE ( 'real32' )
+         return_value = NF90_FLOAT
+
+      CASE ( 'real64' )
+         return_value = NF90_DOUBLE
+#endif
+
+      CASE DEFAULT
+         CALL internal_message( 'error', routine_name // &
+                                         ': data type unknown (' // TRIM( data_type ) // ')' )
+         return_value = -1_iwp
+
+   END SELECT
+
+END FUNCTION get_netcdf_data_type
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Message routine writing debug information into the debug file
+!> or creating the error message string.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE internal_message( level, string )
+
+   CHARACTER(LEN=*), INTENT(IN) ::  level   !< message importance level
+   CHARACTER(LEN=*), INTENT(IN) ::  string  !< message string
+
+
+   IF ( TRIM( level ) == 'error' )  THEN
+
+      WRITE( internal_error_message, '(A,A)' ) ': ', string
+
+   ELSEIF ( TRIM( level ) == 'debug'  .AND.  print_debug_output )  THEN
+
+      WRITE( debug_output_unit, '(A,A)' ) 'DOM DEBUG: ', string
+      FLUSH( debug_output_unit )
+
+   ENDIF
+
+END SUBROUTINE internal_message
+
+!--------------------------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Return the last created error message.
+!--------------------------------------------------------------------------------------------------!
+SUBROUTINE netcdf4_get_error_message( error_message )
+
+   CHARACTER(LEN=800), INTENT(OUT) ::  error_message  !< return error message to main program
+
+
+   error_message = internal_error_message
+
+END SUBROUTINE netcdf4_get_error_message
+
+
+END MODULE data_output_netcdf4_module
Index: lm/trunk/SOURCE/data_output_netcdf4_parallel_module.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_netcdf4_parallel_module.f90	(revision 4105)
+++ 	(revision )
@@ -1,787 +1,0 @@
-!> @file data_output_netcdf4_parallel_module.f90
-!--------------------------------------------------------------------------------------------------!
-! This file is part of the PALM model system.
-!
-! PALM is free software: you can redistribute it and/or modify it under the
-! terms of the GNU General Public License as published by the Free Software
-! Foundation, either version 3 of the License, or (at your option) any later
-! version.
-!
-! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-!
-! You should have received a copy of the GNU General Public License along with
-! PALM. If not, see <http://www.gnu.org/licenses/>.
-!
-! Copyright 2019-2019 Leibniz Universitaet Hannover
-!--------------------------------------------------------------------------------------------------!
-!
-! Current revisions:
-! ------------------
-! 
-! 
-! Former revisions:
-! -----------------
-! $Id$
-! Initial revision
-!
-!
-! Authors:
-! --------
-!> @author: Tobias Gronemeier
-!
-! Description:
-! ------------
-!> NetCDF output module to write data to NetCDF files using parallel NetCDF.
-!>
-!> @todo Think of removing 'is_init' as its value can be derived from the return
-!>       value of 'return_value'.
-!--------------------------------------------------------------------------------------------------!
-MODULE data_output_netcdf4_parallel_module
-
-   USE kinds
-
-#if defined( __parallel )
-#if defined( __mpifh )
-   INCLUDE "mpif.h"
-#else
-   USE MPI
-#endif
-#endif
-
-#if defined( __netcdf4_parallel )
-   USE NETCDF
-#endif
-
-   IMPLICIT NONE
-
-   CHARACTER(LEN=800) ::  internal_error_message = ''  !< string containing the last error message
-   CHARACTER(LEN=800) ::  temp_string                  !< dummy string
-
-   INTEGER(iwp) ::  debug_output_unit       !< Fortran Unit Number of the debug-output file
-   INTEGER(iwp) ::  global_id_in_file = -1  !< value of global ID within a file
-
-   LOGICAL ::  print_debug_output = .FALSE.  !< if true, debug output is printed
-
-   SAVE
-
-   PRIVATE
-
-   INTERFACE netcdf4_parallel_init_module
-      MODULE PROCEDURE netcdf4_parallel_init_module
-   END INTERFACE netcdf4_parallel_init_module
-
-   INTERFACE netcdf4_parallel_open_file
-      MODULE PROCEDURE netcdf4_parallel_open_file
-   END INTERFACE netcdf4_parallel_open_file
-
-   INTERFACE netcdf4_parallel_init_dimension
-      MODULE PROCEDURE netcdf4_parallel_init_dimension
-   END INTERFACE netcdf4_parallel_init_dimension
-
-   INTERFACE netcdf4_parallel_init_variable
-      MODULE PROCEDURE netcdf4_parallel_init_variable
-   END INTERFACE netcdf4_parallel_init_variable
-
-   INTERFACE netcdf4_parallel_write_attribute
-      MODULE PROCEDURE netcdf4_parallel_write_attribute
-   END INTERFACE netcdf4_parallel_write_attribute
-
-   INTERFACE netcdf4_parallel_init_end
-      MODULE PROCEDURE netcdf4_parallel_init_end
-   END INTERFACE netcdf4_parallel_init_end
-
-   INTERFACE netcdf4_parallel_write_variable
-      MODULE PROCEDURE netcdf4_parallel_write_variable
-   END INTERFACE netcdf4_parallel_write_variable
-
-   INTERFACE netcdf4_parallel_finalize
-      MODULE PROCEDURE netcdf4_parallel_finalize
-   END INTERFACE netcdf4_parallel_finalize
-
-   INTERFACE netcdf4_parallel_get_error_message
-      MODULE PROCEDURE netcdf4_parallel_get_error_message
-   END INTERFACE netcdf4_parallel_get_error_message
-
-   PUBLIC &
-      netcdf4_parallel_finalize, &
-      netcdf4_parallel_get_error_message, &
-      netcdf4_parallel_init_dimension, &
-      netcdf4_parallel_init_end, &
-      netcdf4_parallel_init_module, &
-      netcdf4_parallel_init_variable, &
-      netcdf4_parallel_open_file, &
-      netcdf4_parallel_write_attribute, &
-      netcdf4_parallel_write_variable
-
-
-CONTAINS
-
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Initialize data-output module.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_init_module( program_debug_output_unit, debug_output, dom_global_id )
-
-   INTEGER(iwp), INTENT(IN) ::  dom_global_id              !< global id within a file defined by DOM
-   INTEGER(iwp), INTENT(IN) ::  program_debug_output_unit  !< file unit number for debug output
-
-   LOGICAL, INTENT(IN) ::  debug_output  !< if true, debug output is printed
-
-
-   debug_output_unit = program_debug_output_unit
-
-   print_debug_output = debug_output
-
-   global_id_in_file = dom_global_id
-
-
-END SUBROUTINE netcdf4_parallel_init_module
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Open netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_open_file( filename, file_id, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  filename  !< name of file
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_open_file'  !< name of this routine
-
-   INTEGER(iwp), INTENT(OUT) ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-
-#if defined( __parallel ) && defined( __netcdf4_parallel )
-   return_value = 0
-
-   !-- Open new file
-   CALL internal_message( 'debug', routine_name // ': create file "' // TRIM( filename ) // '"' )
-
-   nc_stat = NF90_CREATE( TRIM( filename ),                                       &
-                          IOR( NF90_NOCLOBBER, IOR( NF90_NETCDF4, NF90_MPIIO ) ), &
-                          file_id, COMM = MPI_COMM_WORLD, INFO = MPI_INFO_NULL )
-
-   IF ( nc_stat /= NF90_NOERR )  THEN
-      return_value = 1
-      CALL internal_message( 'error', routine_name // ': NetCDF error while opening file "' // &
-                                      TRIM( filename ) // '": ' // NF90_STRERROR( nc_stat ) )
-   ENDIF
-#else
-   file_id = -1
-   nc_stat = 0
-   return_value = 1
-   CALL internal_message( 'error', routine_name //                      &
-                          ': pre-processor directives "__parallel" ' // &
-                          'and/or "__netcdf4_parallel" not given. ' //  &
-                          'Using parallel NetCDF4 output not possible' )
-#endif
-
-END SUBROUTINE netcdf4_parallel_open_file
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Write attribute to netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_write_attribute( file_id, var_id, att_name, att_value_char, &
-                 att_value_int8, att_value_int16, att_value_int32,                      &
-                 att_value_real32, att_value_real64, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN)           ::  att_name        !< name of attribute
-   CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  att_value_char  !< value of attribute
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_write_attribute'  !< name of this routine
-
-   INTEGER(iwp) ::  nc_stat    !< netcdf return value
-   INTEGER(iwp) ::  target_id  !< ID of target which gets attribute (either global or var_id)
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(IN)  ::  var_id        !< variable ID
-
-   INTEGER(KIND=1), INTENT(IN), OPTIONAL ::  att_value_int8   !< value of attribute
-   INTEGER(KIND=2), INTENT(IN), OPTIONAL ::  att_value_int16  !< value of attribute
-   INTEGER(KIND=4), INTENT(IN), OPTIONAL ::  att_value_int32  !< value of attribute
-
-   REAL(KIND=4), INTENT(IN), OPTIONAL ::  att_value_real32  !< value of attribute
-   REAL(KIND=8), INTENT(IN), OPTIONAL ::  att_value_real64  !< value of attribute
-
-
-#if defined( __netcdf4_parallel )
-   return_value = 0
-
-   IF ( var_id == global_id_in_file )  THEN
-      target_id = NF90_GLOBAL
-   ELSE
-      target_id = var_id
-   ENDIF
-
-   CALL internal_message( 'debug', &
-                          routine_name // ': write attribute "' // TRIM( att_name ) // '"' )
-
-   IF ( PRESENT( att_value_char ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), TRIM( att_value_char ) )
-   ELSEIF ( PRESENT( att_value_int8 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int8 )
-   ELSEIF ( PRESENT( att_value_int16 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int16 )
-   ELSEIF ( PRESENT( att_value_int32 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int32 )
-   ELSEIF ( PRESENT( att_value_real32 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_real32 )
-   ELSEIF ( PRESENT( att_value_real64 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_real64 )
-   ELSE
-      return_value = 1
-      CALL internal_message( 'error', TRIM( routine_name ) // &
-                                      ': attribute "' // TRIM( att_name ) // '": no value given' )
-   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( att_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-      ENDIF
-   ENDIF
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_parallel_write_attribute
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Initialize dimension.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_init_dimension( file_id, dim_id, var_id, &
-              dim_name, dim_type, dim_length, is_init, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  dim_name  !< name of dimension
-   CHARACTER(LEN=*), INTENT(IN) ::  dim_type  !< data type of dimension
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_init_dimension'  !< name of this routine
-
-   INTEGER(iwp), INTENT(OUT) ::  dim_id         !< dimension ID
-   INTEGER(iwp), INTENT(IN)  ::  dim_length     !< length of dimension
-   INTEGER(iwp), INTENT(IN)  ::  file_id        !< file ID
-   INTEGER(iwp)              ::  nc_dim_length  !< length of dimension
-   INTEGER(iwp)              ::  nc_stat        !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value   !< return value
-   INTEGER(iwp), INTENT(OUT) ::  var_id         !< variable ID
-
-   LOGICAL, INTENT(OUT) ::  is_init  !< true if dimension is initialized
-
-
-#if defined( __netcdf4_parallel )
-   return_value = 0
-   var_id = -1
-
-   CALL internal_message( 'debug', routine_name // ': init dimension "' // TRIM( dim_name ) // '"' )
-
-   !-- Check if dimension is unlimited
-   IF ( dim_length < 0 )  THEN
-      nc_dim_length = NF90_UNLIMITED
-   ELSE
-      nc_dim_length = dim_length
-   ENDIF
-
-   !-- Define dimension in file
-   nc_stat = NF90_DEF_DIM( file_id, dim_name, nc_dim_length, dim_id )
-
-   IF ( nc_stat == NF90_NOERR )  THEN
-
-      !-- Define variable holding dimension values in file
-      CALL netcdf4_parallel_init_variable( file_id, var_id, dim_name, dim_type, (/dim_id/), &
-                                           is_init, is_global=.TRUE., return_value=return_value )
-
-   ELSE
-      return_value = 1
-      is_init = .FALSE.
-      CALL internal_message( 'error', routine_name //                                    &
-                                      ': NetCDF error while initializing dimension "' // &
-                                      TRIM( dim_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-   ENDIF
-#else
-   return_value = 1
-   var_id = -1
-   dim_id = -1
-   is_init = .FALSE.
-#endif
-
-END SUBROUTINE netcdf4_parallel_init_dimension
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Initialize variable.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_init_variable( file_id, var_id, var_name, var_type, var_dim_ids, &
-                                           is_init, is_global, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  var_name  !< name of variable
-   CHARACTER(LEN=*), INTENT(IN) ::  var_type  !< data type of variable
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_init_variable'  !< name of this routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp)              ::  nc_var_type   !< netcdf data type
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(OUT) ::  var_id        !< variable ID
-
-   INTEGER(iwp), DIMENSION(:), INTENT(IN) ::  var_dim_ids  !< list of dimension IDs used by variable
-
-   LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global (same on all PE)
-   LOGICAL, INTENT(OUT) ::  is_init    !< true if variable is initialized
-
-
-#if defined( __netcdf4_parallel )
-   return_value = 0
-
-   WRITE( temp_string, * ) is_global
-   CALL internal_message( 'debug', routine_name // ': init variable "' // TRIM( var_name ) // &
-                                   '" ( is_global = ' // TRIM( temp_string ) // ')' )
-
-   nc_var_type = get_netcdf_data_type( var_type )
-
-   IF ( nc_var_type /= -1_iwp )  THEN
-
-      !-- Define variable in file
-      nc_stat = NF90_DEF_VAR( file_id, var_name, nc_var_type, var_dim_ids, var_id )
-
-      IF ( nc_stat == NF90_NOERR )  THEN
-         IF ( is_global )  THEN
-            nc_stat = NF90_VAR_PAR_ACCESS( file_id, var_id, NF90_INDEPENDENT )
-         ELSE
-            nc_stat = NF90_VAR_PAR_ACCESS( file_id, var_id, NF90_COLLECTIVE )
-         ENDIF
-      ENDIF
-
-      IF ( nc_stat /= NF90_NOERR)  THEN
-         return_value = 1
-         CALL internal_message( 'error', routine_name //                                   &
-                                         ': NetCDF error while initializing variable "' // &
-                                         TRIM( var_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-      ENDIF
-
-   ELSE
-      return_value = 1
-   ENDIF
-
-   is_init = return_value == 0
-#else
-   return_value = 1
-   var_id = -1
-   is_init = .FALSE.
-#endif
-
-END SUBROUTINE netcdf4_parallel_init_variable
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Leave file definition state.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_init_end( file_id, return_value )
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_init_end'  !< name of this routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp)              ::  old_mode      !< previous netcdf fill mode
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-
-#if defined( __netcdf4_parallel )
-   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_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
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_parallel_init_end
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Write variable of different kind into netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_write_variable(                               &
-              file_id, var_id, bounds_start, bounds_end, bounds_origin,   &
-              do_output, is_global,                                       &
-              var_int8_0d,   var_int8_1d,   var_int8_2d,   var_int8_3d,   &
-              var_int16_0d,  var_int16_1d,  var_int16_2d,  var_int16_3d,  &
-              var_int32_0d,  var_int32_1d,  var_int32_2d,  var_int32_3d,  &
-              var_intwp_0d,  var_intwp_1d,  var_intwp_2d,  var_intwp_3d,  &
-              var_real32_0d, var_real32_1d, var_real32_2d, var_real32_3d, &
-              var_real64_0d, var_real64_1d, var_real64_2d, var_real64_3d, &
-              var_realwp_0d, var_realwp_1d, var_realwp_2d, var_realwp_3d, &
-              return_value )
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_write_variable'  !< name of this routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  myid = 0      !< id number of processor element
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(IN)  ::  var_id        !< variable ID
-
-   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_origin  !< starting index of each dimension
-   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_end     !< ending index of variable
-   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_start   !< starting index of variable
-   INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  value_count    !< count of values along each dimension to be written
-
-   INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL                               ::  var_int8_0d  !< output variable
-   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int8_1d  !< output variable
-   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int8_2d  !< output variable
-   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int8_3d  !< output variable
-
-   INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL                               ::  var_int16_0d  !< output variable
-   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int16_1d  !< output variable
-   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int16_2d  !< output variable
-   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int16_3d  !< output variable
-
-   INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL                               ::  var_int32_0d  !< output variable
-   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int32_1d  !< output variable
-   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int32_2d  !< output variable
-   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int32_3d  !< output variable
-
-   INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL                               ::  var_intwp_0d  !< output variable
-   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_intwp_1d  !< output variable
-   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_intwp_2d  !< output variable
-   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_intwp_3d  !< output variable
-
-   LOGICAL, INTENT(IN) ::  do_output  !< if false, set count to 0 and do no output
-   LOGICAL, INTENT(IN) ::  is_global  !< true if variable is global (same on all PE)
-
-   REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL                               ::  var_real32_0d  !< output variable
-   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_real32_1d  !< output variable
-   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_real32_2d  !< output variable
-   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_real32_3d  !< output variable
-
-   REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL                               ::  var_real64_0d  !< output variable
-   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_real64_1d  !< output variable
-   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_real64_2d  !< output variable
-   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_real64_3d  !< output variable
-
-   REAL(wp), POINTER, INTENT(IN), OPTIONAL                               ::  var_realwp_0d  !< output variable
-   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_realwp_1d  !< output variable
-   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_realwp_2d  !< output variable
-   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_realwp_3d  !< output variable
-
-
-#if defined( __netcdf4_parallel )
-   return_value = 0
-
-#if defined( __parallel )
-   CALL MPI_COMM_RANK( MPI_COMM_WORLD, myid, return_value )
-   IF ( return_value /= 0 )  THEN
-      CALL internal_message( 'error', routine_name // ': MPI_COMM_RANK error' )
-   ENDIF
-#endif
-
-   IF ( return_value == 0  .AND.  ( .NOT. is_global  .OR.  myid == 0 ) )  THEN
-
-      WRITE( temp_string, * ) var_id
-      CALL internal_message( 'debug', routine_name // ': write variable ' // TRIM( temp_string ) )
-
-      ALLOCATE( value_count(SIZE( bounds_start )) )
-
-      IF ( do_output ) THEN
-         value_count = bounds_end - bounds_start + 1
-      ELSE
-         value_count = 0
-      END IF
-
-      !-- 8bit integer output
-      IF ( PRESENT( var_int8_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int8_0d /),       &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int8_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_1d,             &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int8_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_2d,             &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int8_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_3d,             &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 16bit integer output
-      ELSEIF ( PRESENT( var_int16_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int16_0d /),      &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int16_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_1d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int16_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_2d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int16_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_3d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 32bit integer output
-      ELSEIF ( PRESENT( var_int32_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int32_0d /),      &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int32_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_1d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int32_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_2d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int32_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_3d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- working-precision integer output
-      ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_intwp_0d /),      &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_1d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_2d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_3d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 32bit real output
-      ELSEIF ( PRESENT( var_real32_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_real32_0d /),     &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real32_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_1d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real32_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_2d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real32_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_3d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 64bit real output
-      ELSEIF ( PRESENT( var_real64_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_real64_0d /),     &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real64_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_1d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real64_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_2d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real64_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_3d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- working-precision real output
-      ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_realwp_0d /),     &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_1d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_2d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_3d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSE
-         return_value = 1
-         nc_stat = NF90_NOERR
-         WRITE( temp_string, '(": variable_id=",I6,", file_id=",I6)' ) var_id, file_id
-         CALL internal_message( 'error', routine_name // &
-                                TRIM( temp_string ) //   &
-                                ': no output values given' )
-      ENDIF
-
-      !-- Check for errors
-      IF ( nc_stat /= NF90_NOERR )  THEN
-         return_value = 1
-         WRITE( temp_string, * ) 'variable_id=', var_id, '; file_id=', file_id, &
-                                 ', bounds_start=', bounds_start,               &
-                                 ', bounds_end=', bounds_end,                   &
-                                 ', count=', value_count
-         CALL internal_message( 'error', routine_name //                                    &
-                                         ': error while writing ' // TRIM( temp_string ) // &
-                                         ': NetCDF error: ' // NF90_STRERROR( nc_stat ) )
-      ENDIF
-
-   ENDIF
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_parallel_write_variable
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Close netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_finalize( file_id, return_value )
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_parallel_finalize'  !< name of routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-
-#if defined( __netcdf4_parallel )
-   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
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_parallel_finalize
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Convert data_type string into netcdf data type value.
-!--------------------------------------------------------------------------------------------------!
-FUNCTION get_netcdf_data_type( data_type ) RESULT( return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  data_type  !< requested data type
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'get_netcdf_data_type'  !< name of this routine
-
-   INTEGER(iwp) ::  return_value  !< netcdf data type
-
-
-   SELECT CASE ( TRIM( data_type ) )
-
-#if defined( __netcdf4_parallel )
-      CASE ( 'char' )
-         return_value = NF90_CHAR
-
-      CASE ( 'int8' )
-         return_value = NF90_BYTE
-
-      CASE ( 'int16' )
-         return_value = NF90_SHORT
-
-      CASE ( 'int32' )
-         return_value = NF90_INT
-
-      CASE ( 'real32' )
-         return_value = NF90_FLOAT
-
-      CASE ( 'real64' )
-         return_value = NF90_DOUBLE
-#endif
-
-      CASE DEFAULT
-         CALL internal_message( 'error', routine_name // &
-                                         ': data type unknown (' // TRIM( data_type ) // ')' )
-         return_value = -1_iwp
-
-   END SELECT
-
-END FUNCTION get_netcdf_data_type
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Message routine writing debug information into the debug file
-!> or creating the error message string.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE internal_message( level, string )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  level   !< message importance level
-   CHARACTER(LEN=*), INTENT(IN) ::  string  !< message string
-
-
-   IF ( TRIM( level ) == 'error' )  THEN
-
-      WRITE( internal_error_message, '(A,A)' ) 'DOM ERROR: ', string
-
-   ELSEIF ( TRIM( level ) == 'debug'  .AND.  print_debug_output )  THEN
-
-      WRITE( debug_output_unit, '(A,A)' ) 'DOM DEBUG: ', string
-      FLUSH( debug_output_unit )
-
-   ENDIF
-
-END SUBROUTINE internal_message
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Return the last created error message.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_parallel_get_error_message( error_message )
-
-   CHARACTER(LEN=800), INTENT(OUT) ::  error_message  !< return error message to main program
-
-
-   error_message = internal_error_message
-
-END SUBROUTINE netcdf4_parallel_get_error_message
-
-
-END MODULE data_output_netcdf4_parallel_module
Index: lm/trunk/SOURCE/data_output_netcdf4_serial_module.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_netcdf4_serial_module.f90	(revision 4105)
+++ 	(revision )
@@ -1,780 +1,0 @@
-!> @file data_output_netcdf4_serial_module.f90
-!--------------------------------------------------------------------------------------------------!
-! This file is part of the PALM model system.
-!
-! PALM is free software: you can redistribute it and/or modify it under the
-! terms of the GNU General Public License as published by the Free Software
-! Foundation, either version 3 of the License, or (at your option) any later
-! version.
-!
-! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-!
-! You should have received a copy of the GNU General Public License along with
-! PALM. If not, see <http://www.gnu.org/licenses/>.
-!
-! Copyright 2019-2019 Leibniz Universitaet Hannover
-!--------------------------------------------------------------------------------------------------!
-!
-! Current revisions:
-! ------------------
-! 
-! 
-! Former revisions:
-! -----------------
-! $Id$
-! Initial revision
-!
-!
-! Authors:
-! --------
-!> @author: Tobias Gronemeier
-!
-! Description:
-! ------------
-!> Netcdf output module to write data to NetCDF files by single processor
-!>
-!> @todo Think of removing 'is_init' as its value can be derived from the return
-!>       value of 'return_value'.
-!--------------------------------------------------------------------------------------------------!
-MODULE data_output_netcdf4_serial_module
-
-   USE kinds
-
-#if defined( __parallel )
-#if defined( __mpifh )
-   INCLUDE "mpif.h"
-#else
-   USE MPI
-#endif
-#endif
-
-#if defined( __netcdf4 )
-   USE NETCDF
-#endif
-
-   IMPLICIT NONE
-
-   CHARACTER(LEN=800) ::  internal_error_message = ''  !< string containing the last error message
-   CHARACTER(LEN=800) ::  temp_string                  !< dummy string
-
-   INTEGER(iwp) ::  debug_output_unit       !< Fortran Unit Number of the debug-output file
-   INTEGER(iwp) ::  global_id_in_file = -1  !< value of global ID within a file
-
-   LOGICAL ::  print_debug_output = .FALSE.  !< if true, debug output is printed
-
-   SAVE
-
-   PRIVATE
-
-   INTERFACE netcdf4_serial_init_module
-      MODULE PROCEDURE netcdf4_serial_init_module
-   END INTERFACE netcdf4_serial_init_module
-
-   INTERFACE netcdf4_serial_open_file
-      MODULE PROCEDURE netcdf4_serial_open_file
-   END INTERFACE netcdf4_serial_open_file
-
-   INTERFACE netcdf4_serial_init_dimension
-      MODULE PROCEDURE netcdf4_serial_init_dimension
-   END INTERFACE netcdf4_serial_init_dimension
-
-   INTERFACE netcdf4_serial_init_variable
-      MODULE PROCEDURE netcdf4_serial_init_variable
-   END INTERFACE netcdf4_serial_init_variable
-
-   INTERFACE netcdf4_serial_write_attribute
-      MODULE PROCEDURE netcdf4_serial_write_attribute
-   END INTERFACE netcdf4_serial_write_attribute
-
-   INTERFACE netcdf4_serial_init_end
-      MODULE PROCEDURE netcdf4_serial_init_end
-   END INTERFACE netcdf4_serial_init_end
-
-   INTERFACE netcdf4_serial_write_variable
-      MODULE PROCEDURE netcdf4_serial_write_variable
-   END INTERFACE netcdf4_serial_write_variable
-
-   INTERFACE netcdf4_serial_finalize
-      MODULE PROCEDURE netcdf4_serial_finalize
-   END INTERFACE netcdf4_serial_finalize
-
-   INTERFACE netcdf4_serial_get_error_message
-      MODULE PROCEDURE netcdf4_serial_get_error_message
-   END INTERFACE netcdf4_serial_get_error_message
-
-   PUBLIC &
-   netcdf4_serial_finalize, &
-   netcdf4_serial_get_error_message, &
-   netcdf4_serial_init_dimension, &
-   netcdf4_serial_init_end, &
-   netcdf4_serial_init_module, &
-   netcdf4_serial_init_variable, &
-   netcdf4_serial_open_file, &
-   netcdf4_serial_write_attribute, &
-   netcdf4_serial_write_variable
-
-
-CONTAINS
-
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Initialize data-output module.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_init_module( program_debug_output_unit, debug_output, dom_global_id )
-
-   INTEGER(iwp), INTENT(IN) ::  dom_global_id              !< global id within a file defined by DOM
-   INTEGER(iwp), INTENT(IN) ::  program_debug_output_unit  !< file unit number for debug output
-
-   LOGICAL, INTENT(IN) ::  debug_output  !< if true, debug output is printed
-
-
-   debug_output_unit = program_debug_output_unit
-
-   print_debug_output = debug_output
-
-   global_id_in_file = dom_global_id
-
-END SUBROUTINE netcdf4_serial_init_module
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Open netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_open_file( filename, file_id, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  filename  !< name of file
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_open_file'  !< name of this routine
-
-   INTEGER(iwp), INTENT(OUT) ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-
-#if defined( __netcdf4 )
-   return_value = 0
-
-   !-- Open new file
-   CALL internal_message( 'debug', routine_name // ': create file "' // TRIM( filename ) // '"' )
-
-   nc_stat = NF90_CREATE( TRIM( filename ),                    &
-                          IOR( NF90_NOCLOBBER, NF90_NETCDF4 ), &
-                          file_id )
-
-   IF ( nc_stat /= NF90_NOERR )  THEN
-      return_value = 1
-      CALL internal_message( 'error', routine_name // ': NetCDF error while opening file "' // &
-                                      TRIM( filename ) // '": ' // NF90_STRERROR( nc_stat ) )
-   ENDIF
-#else
-   file_id = -1
-   return_value = 1
-   CALL internal_message( 'error', routine_name //                               &
-                          ': pre-processor directive "__netcdf4" not given. ' // &
-                          'Using NetCDF4 output not possible' )
-#endif
-
-END SUBROUTINE netcdf4_serial_open_file
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Write attribute to netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_write_attribute( file_id, var_id, att_name, att_value_char, &
-                 att_value_int8, att_value_int16, att_value_int32,                    &
-                 att_value_real32, att_value_real64, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN)           ::  att_name        !< name of attribute
-   CHARACTER(LEN=*), INTENT(IN), OPTIONAL ::  att_value_char  !< value of attribute
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_write_attribute'  !< name of this routine
-
-   INTEGER(iwp) ::  nc_stat    !< netcdf return value
-   INTEGER(iwp) ::  target_id  !< ID of target which gets attribute (either global or var_id)
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(IN)  ::  var_id        !< variable ID
-
-   INTEGER(KIND=1), INTENT(IN), OPTIONAL ::  att_value_int8   !< value of attribute
-   INTEGER(KIND=2), INTENT(IN), OPTIONAL ::  att_value_int16  !< value of attribute
-   INTEGER(KIND=4), INTENT(IN), OPTIONAL ::  att_value_int32  !< value of attribute
-
-   REAL(KIND=4), INTENT(IN), OPTIONAL ::  att_value_real32  !< value of attribute
-   REAL(KIND=8), INTENT(IN), OPTIONAL ::  att_value_real64  !< value of attribute
-
-
-#if defined( __netcdf4 )
-   return_value = 0
-
-   IF ( var_id == global_id_in_file )  THEN
-      target_id = NF90_GLOBAL
-   ELSE
-      target_id = var_id
-   ENDIF
-
-   CALL internal_message( 'debug', &
-                          routine_name // ': write attribute "' // TRIM( att_name ) // '"' )
-
-   IF ( PRESENT( att_value_char ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), TRIM( att_value_char ) )
-   ELSEIF ( PRESENT( att_value_int8 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int8 )
-   ELSEIF ( PRESENT( att_value_int16 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int16 )
-   ELSEIF ( PRESENT( att_value_int32 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_int32 )
-   ELSEIF ( PRESENT( att_value_real32 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_real32 )
-   ELSEIF ( PRESENT( att_value_real64 ) )  THEN
-      nc_stat = NF90_PUT_ATT( file_id, target_id, TRIM( att_name ), att_value_real64 )
-   ELSE
-      return_value = 1
-      CALL internal_message( 'error', TRIM( routine_name ) // &
-                                      ': attribute "' // TRIM( att_name ) // '": no value given' )
-   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( att_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-      ENDIF
-   ENDIF
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_serial_write_attribute
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Initialize dimension.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_init_dimension( file_id, dim_id, var_id, &
-              dim_name, dim_type, dim_length, is_init, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  dim_name  !< name of dimension
-   CHARACTER(LEN=*), INTENT(IN) ::  dim_type  !< data type of dimension
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_init_dimension'  !< name of this routine
-
-   INTEGER(iwp), INTENT(OUT) ::  dim_id         !< dimension ID
-   INTEGER(iwp), INTENT(IN)  ::  dim_length     !< length of dimension
-   INTEGER(iwp), INTENT(IN)  ::  file_id        !< file ID
-   INTEGER(iwp)              ::  nc_dim_length  !< length of dimension
-   INTEGER(iwp)              ::  nc_stat        !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value   !< return value
-   INTEGER(iwp), INTENT(OUT) ::  var_id         !< variable ID
-
-   LOGICAL, INTENT(OUT) ::  is_init  !< true if dimension is initialized
-
-
-#if defined( __netcdf4 )
-   return_value = 0
-   var_id = -1
-
-   CALL internal_message( 'debug', routine_name // ': init dimension "' // TRIM( dim_name ) // '"' )
-
-   !-- Check if dimension is unlimited
-   IF ( dim_length < 0 )  THEN
-      nc_dim_length = NF90_UNLIMITED
-   ELSE
-      nc_dim_length = dim_length
-   ENDIF
-
-   !-- Define dimension in file
-   nc_stat = NF90_DEF_DIM( file_id, dim_name, nc_dim_length, dim_id )
-
-   IF ( nc_stat == NF90_NOERR )  THEN
-
-      !-- Define variable holding dimension values in file
-      CALL netcdf4_serial_init_variable( file_id, var_id, dim_name, dim_type, (/dim_id/), &
-                                         is_init, is_global=.TRUE., return_value=return_value )
-
-   ELSE
-      return_value = 1
-      is_init = .FALSE.
-      CALL internal_message( 'error', routine_name //                                    &
-                                      ': NetCDF error while initializing dimension "' // &
-                                      TRIM( dim_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-   ENDIF
-#else
-   return_value = 1
-   var_id = -1
-   dim_id = -1
-   is_init = .FALSE.
-#endif
-
-END SUBROUTINE netcdf4_serial_init_dimension
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Initialize variable.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_init_variable( file_id, var_id, var_name, var_type, var_dim_ids, &
-                                         is_init, is_global, return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  var_name  !< name of variable
-   CHARACTER(LEN=*), INTENT(IN) ::  var_type  !< data type of variable
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_init_variable'  !< name of this routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp)              ::  nc_var_type   !< netcdf data type
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(OUT) ::  var_id        !< variable ID
-
-   INTEGER(iwp), DIMENSION(:), INTENT(IN) ::  var_dim_ids  !< list of dimension IDs used by variable
-
-   LOGICAL, INTENT(IN)  ::  is_global  !< true if variable is global (same on all PE)
-   LOGICAL, INTENT(OUT) ::  is_init    !< true if variable is initialized
-
-
-#if defined( __netcdf4 )
-   return_value = 0
-
-   WRITE( temp_string, * ) is_global
-   CALL internal_message( 'debug', routine_name // ': init variable "' // TRIM( var_name ) // &
-                                   '" ( is_global = ' // TRIM( temp_string ) // ')' )
-
-   nc_var_type = get_netcdf_data_type( var_type )
-
-   IF ( nc_var_type /= -1_iwp )  THEN
-
-      !-- Define variable in file
-      nc_stat = NF90_DEF_VAR( file_id, var_name, nc_var_type, var_dim_ids, var_id )
-
-      IF ( is_global )  CONTINUE  ! Added to be consistent to parallel output
-
-      IF ( nc_stat /= NF90_NOERR )  THEN
-         return_value = 1
-         CALL internal_message( 'error', routine_name //                                   &
-                                         ': NetCDF error while initializing variable "' // &
-                                         TRIM( var_name ) // '": ' // NF90_STRERROR( nc_stat ) )
-      ENDIF
-
-   ELSE
-      return_value = 1
-   ENDIF
-
-   is_init = return_value == 0
-#else
-   return_value = 1
-   var_id = -1
-   is_init = .FALSE.
-#endif
-
-END SUBROUTINE netcdf4_serial_init_variable
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Leave file definition state.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_init_end( file_id, return_value )
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_init_end'  !< name of this routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp)              ::  old_mode      !< previous netcdf fill mode
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-
-#if defined( __netcdf4 )
-   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_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
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_serial_init_end
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Write variable of different kind into netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_write_variable(                                 &
-              file_id, var_id, bounds_start, bounds_end, bounds_origin,   &
-              do_output, is_global,                                       &
-              var_int8_0d,   var_int8_1d,   var_int8_2d,   var_int8_3d,   &
-              var_int16_0d,  var_int16_1d,  var_int16_2d,  var_int16_3d,  &
-              var_int32_0d,  var_int32_1d,  var_int32_2d,  var_int32_3d,  &
-              var_intwp_0d,  var_intwp_1d,  var_intwp_2d,  var_intwp_3d,  &
-              var_real32_0d, var_real32_1d, var_real32_2d, var_real32_3d, &
-              var_real64_0d, var_real64_1d, var_real64_2d, var_real64_3d, &
-              var_realwp_0d, var_realwp_1d, var_realwp_2d, var_realwp_3d, &
-              return_value )
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_write_variable'  !< name of this routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  myid = 0      !< id number of processor element
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-   INTEGER(iwp), INTENT(IN)  ::  var_id        !< variable ID
-
-   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_origin  !< starting index of each dimension
-   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_end     !< ending index of variable
-   INTEGER(iwp), DIMENSION(:), INTENT(IN)  ::  bounds_start   !< starting index of variable
-   INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  value_count    !< count of values along each dimension to be written
-
-   INTEGER(KIND=1), POINTER, INTENT(IN), OPTIONAL                               ::  var_int8_0d  !< output variable
-   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int8_1d  !< output variable
-   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int8_2d  !< output variable
-   INTEGER(KIND=1), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int8_3d  !< output variable
-
-   INTEGER(KIND=2), POINTER, INTENT(IN), OPTIONAL                               ::  var_int16_0d  !< output variable
-   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int16_1d  !< output variable
-   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int16_2d  !< output variable
-   INTEGER(KIND=2), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int16_3d  !< output variable
-
-   INTEGER(KIND=4), POINTER, INTENT(IN), OPTIONAL                               ::  var_int32_0d  !< output variable
-   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_int32_1d  !< output variable
-   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_int32_2d  !< output variable
-   INTEGER(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_int32_3d  !< output variable
-
-   INTEGER(iwp), POINTER, INTENT(IN), OPTIONAL                               ::  var_intwp_0d  !< output variable
-   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_intwp_1d  !< output variable
-   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_intwp_2d  !< output variable
-   INTEGER(iwp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_intwp_3d  !< output variable
-
-   LOGICAL, INTENT(IN) ::  do_output  !< if false, set count to 0 and do no output
-   LOGICAL, INTENT(IN) ::  is_global  !< true if variable is global (same on all PE)
-
-   REAL(KIND=4), POINTER, INTENT(IN), OPTIONAL                               ::  var_real32_0d  !< output variable
-   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_real32_1d  !< output variable
-   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_real32_2d  !< output variable
-   REAL(KIND=4), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_real32_3d  !< output variable
-
-   REAL(KIND=8), POINTER, INTENT(IN), OPTIONAL                               ::  var_real64_0d  !< output variable
-   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_real64_1d  !< output variable
-   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_real64_2d  !< output variable
-   REAL(KIND=8), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_real64_3d  !< output variable
-
-   REAL(wp), POINTER, INTENT(IN), OPTIONAL                               ::  var_realwp_0d  !< output variable
-   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:)     ::  var_realwp_1d  !< output variable
-   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:)   ::  var_realwp_2d  !< output variable
-   REAL(wp), POINTER, CONTIGUOUS, INTENT(IN), OPTIONAL, DIMENSION(:,:,:) ::  var_realwp_3d  !< output variable
-
-
-#if defined( __netcdf4 )
-   return_value = 0
-
-#if defined( __parallel )
-   CALL MPI_COMM_RANK( MPI_COMM_WORLD, myid, return_value )
-   IF ( return_value /= 0 )  THEN
-      CALL internal_message( 'error', routine_name // ': MPI_COMM_RANK error' )
-   ENDIF
-#endif
-
-   IF ( myid == 0 )  THEN
-
-      IF ( is_global )  CONTINUE  ! reqired to prevent compiler warning
-
-      WRITE( temp_string, * ) var_id
-      CALL internal_message( 'debug', routine_name // ': write variable ' // TRIM( temp_string ) )
-
-      ALLOCATE( value_count(SIZE( bounds_start )) )
-
-      IF ( do_output ) THEN
-         value_count = bounds_end - bounds_start + 1
-      ELSE
-         value_count = 0
-      END IF
-
-      !-- 8bit integer output
-      IF ( PRESENT( var_int8_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int8_0d /),       &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int8_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_1d,             &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int8_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_2d,             &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int8_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int8_3d,             &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 16bit integer output
-      ELSEIF ( PRESENT( var_int16_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int16_0d /),      &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int16_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_1d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int16_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_2d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int16_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int16_3d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 32bit integer output
-      ELSEIF ( PRESENT( var_int32_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_int32_0d /),      &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int32_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_1d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int32_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_2d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_int32_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_int32_3d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- working-precision integer output
-      ELSEIF ( PRESENT( var_intwp_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_intwp_0d /),      &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_intwp_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_1d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_intwp_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_2d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_intwp_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_intwp_3d,            &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 32bit real output
-      ELSEIF ( PRESENT( var_real32_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_real32_0d /),     &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real32_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_1d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real32_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_2d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real32_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real32_3d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- 64bit real output
-      ELSEIF ( PRESENT( var_real64_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_real64_0d /),     &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real64_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_1d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real64_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_2d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_real64_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_real64_3d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      !-- working-precision real output
-      ELSEIF ( PRESENT( var_realwp_0d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, (/ var_realwp_0d /),     &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_realwp_1d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_1d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_realwp_2d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_2d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSEIF ( PRESENT( var_realwp_3d ) )  THEN
-         nc_stat = NF90_PUT_VAR( file_id, var_id, var_realwp_3d,           &
-                                 start = bounds_start - bounds_origin + 1, &
-                                 count = value_count )
-      ELSE
-         return_value = 1
-         nc_stat = NF90_NOERR
-         WRITE( temp_string, '(": variable_id=",I6,", file_id=",I6)' ) var_id, file_id
-         CALL internal_message( 'error', routine_name // &
-                                TRIM( temp_string ) //   &
-                                ': no output values given' )
-      ENDIF
-
-      !-- Check for errors
-      IF ( nc_stat /= NF90_NOERR )  THEN
-         return_value = 1
-         WRITE( temp_string, * ) 'variable_id=', var_id, '; file_id=', file_id, &
-                                 ', bounds_start=', bounds_start,               &
-                                 ', bounds_end=', bounds_end,                   &
-                                 ', count=', value_count
-         CALL internal_message( 'error', routine_name //                                    &
-                                         ': error while writing ' // TRIM( temp_string ) // &
-                                         ': NetCDF error: ' // NF90_STRERROR( nc_stat ) )
-      ENDIF
-
-   ENDIF
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_serial_write_variable
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Close netcdf file.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_finalize( file_id, return_value )
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'netcdf4_serial_finalize'  !< name of routine
-
-   INTEGER(iwp), INTENT(IN)  ::  file_id       !< file ID
-   INTEGER(iwp)              ::  nc_stat       !< netcdf return value
-   INTEGER(iwp), INTENT(OUT) ::  return_value  !< return value
-
-
-#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 ) )
-   ENDIF
-#else
-   return_value = 1
-#endif
-
-END SUBROUTINE netcdf4_serial_finalize
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Convert data_type string into netcdf data type value.
-!--------------------------------------------------------------------------------------------------!
-FUNCTION get_netcdf_data_type( data_type ) RESULT( return_value )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  data_type  !< requested data type
-
-   CHARACTER(LEN=*), PARAMETER ::  routine_name = 'get_netcdf_data_type'  !< name of this routine
-
-   INTEGER(iwp) ::  return_value  !< netcdf data type
-
-
-   SELECT CASE ( TRIM( data_type ) )
-
-#if defined( __netcdf4 )
-      CASE ( 'char' )
-         return_value = NF90_CHAR
-
-      CASE ( 'int8' )
-         return_value = NF90_BYTE
-
-      CASE ( 'int16' )
-         return_value = NF90_SHORT
-
-      CASE ( 'int32' )
-         return_value = NF90_INT
-
-      CASE ( 'real32' )
-         return_value = NF90_FLOAT
-
-      CASE ( 'real64' )
-         return_value = NF90_DOUBLE
-#endif
-
-      CASE DEFAULT
-         CALL internal_message( 'error', routine_name // &
-                                         ': data type unknown (' // TRIM( data_type ) // ')' )
-         return_value = -1_iwp
-
-   END SELECT
-
-END FUNCTION get_netcdf_data_type
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Message routine writing debug information into the debug file
-!> or creating the error message string.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE internal_message( level, string )
-
-   CHARACTER(LEN=*), INTENT(IN) ::  level   !< message importance level
-   CHARACTER(LEN=*), INTENT(IN) ::  string  !< message string
-
-
-   IF ( TRIM( level ) == 'error' )  THEN
-
-      WRITE( internal_error_message, '(A,A)' ) 'DOM ERROR: ', string
-
-   ELSEIF ( TRIM( level ) == 'debug'  .AND.  print_debug_output )  THEN
-
-      WRITE( debug_output_unit, '(A,A)' ) 'DOM DEBUG: ', string
-      FLUSH( debug_output_unit )
-
-   ENDIF
-
-END SUBROUTINE internal_message
-
-!--------------------------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Return the last created error message.
-!--------------------------------------------------------------------------------------------------!
-SUBROUTINE netcdf4_serial_get_error_message( error_message )
-
-   CHARACTER(LEN=800), INTENT(OUT) ::  error_message  !< return error message to main program
-
-
-   error_message = internal_error_message
-
-END SUBROUTINE netcdf4_serial_get_error_message
-
-
-END MODULE data_output_netcdf4_serial_module
