source: palm/trunk/UTIL/combine_plot_fields.f90 @ 1976

Last change on this file since 1976 was 1809, checked in by raasch, 9 years ago

last commit documented

  • Property svn:keywords set to Id
File size: 31.1 KB
RevLine 
[1]1 PROGRAM combine_plot_fields
2
3!------------------------------------------------------------------------------!
[1046]4! This file is part of PALM.
5!
6! PALM is free software: you can redistribute it and/or modify it under the terms
7! of the GNU General Public License as published by the Free Software Foundation,
8! either version 3 of the License, or (at your option) any later version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
[1310]17! Copyright 1997-2014  Leibniz Universitaet Hannover
[1046]18!--------------------------------------------------------------------------------!
19!
[691]20! Current revisions:
[1]21! -----------------
[1469]22!
[1809]23!
[226]24! Former revisions:
25! -----------------
26! $Id: combine_plot_fields.f90 1809 2016-04-05 20:13:28Z maronga $
27!
[1809]28! 1808 2016-04-05 19:44:00Z raasch
29! cpu measurements are done with standard FORTRAN routine on every machine
30!
[1552]31! 1551 2015-03-03 14:18:16Z maronga
32! Adjustments for data output of soil model quantities
33!
[1469]34! 1468 2014-09-24 14:06:57Z maronga
35! Adapted for use on up to 6-digit processor cores (not tested)
36!
[1395]37! 1394 2014-05-06 10:17:31Z keck
38! KIND-attribute added to all INTEGER and REAL declaration statements
39!
[1047]40! 1046 2012-11-09 14:38:45Z maronga
41! code put under GPL (PALM 3.9)
42!
[692]43! 691 2011-03-04 08:45:30Z maronga
44! Bugfix: check for precursor ocean runs, removed typo
45!
[494]46! 493 2010-03-01 08:30:24Z raasch
47! Exit in case of already complete NetCDF data (due to parallel output in PALM)
48! cpu measurements included
49!
[226]50! 210 2008-11-06 08:54:02Z raasch
[210]51! Size of pf3d adjusted to the required output size (1 gridpoint less, along
52! all three dimensions), because output of a subset of the data
53! (pf3d(nxa:nxe...) in the NF90_PUT_VAR statement caused segmentation fault
54! with the INTEL compiler.
[191]55! Subdomain data are read into temporary arrays pf_tmp/pf3d_tmp in order to
56! avoid INTEL compiler warnings about (automatic) creation of temporary arrays
[179]57! Bugfix: three misplaced #endif directives
[1]58!
[139]59! 114 2007-10-10 00:03:15Z raasch
60! Bugfix: model_string needed a default value
61!
[114]62! Aug 07    Loop for processing of output by coupled runs, id_string does not
63!           contain modus any longer
64!
[1]65! 18/01/06  Output of time-averaged data
66!
67! 25/05/05  Errors removed
68!
69! 26/04/05  Output in NetCDF format, iso2d and avs output only if parameter
70!           file exists
71!
72! 31/10/01  All comments and messages translated into English
73!
74! 23/02/99  Keine Bearbeitung komprimierter 3D-Daten
75! Ursprungsversion vom 28/07/97
76!
77!
78! Description:
79! ------------
80! This routine combines data of the PALM-subdomains into one file. In PALM
81! every processor element opens its own file and writes 2D- or 3D-binary-data
82! into it (different files are opened for xy-, xz-, yz-cross-sections and
83! 3D-data). For plotting or analyzing these PE-data have to be collected and
84! to be put into single files, which is done by this routine.
85! Output format is NetCDF. Additionally, a data are output in a binary format
86! readable by ISO2D-software (cross-sections) and by AVS (3D-data).
87!------------------------------------------------------------------------------!
88
89#if defined( __netcdf )
90    USE netcdf
91#endif
92
93    IMPLICIT NONE
94
95!
96!-- Local variables
[108]97    CHARACTER (LEN=2)    ::  modus, model_string
[1468]98    CHARACTER (LEN=6)    ::  id_string
[1551]99    CHARACTER (LEN=20)   ::  dimname, var_name
[1]100    CHARACTER (LEN=40)   ::  filename
101
102    CHARACTER (LEN=2000), DIMENSION(0:1) ::  var_list
103
[1394]104    INTEGER, PARAMETER ::  iwp = 4, spk = SELECTED_REAL_KIND( 6 ), wp = 8
[1]105
[1394]106    INTEGER(iwp) ::  av, danz, i, id, j, k, model, models, nc_stat,            &
107                     nxa, nxag, nxe, nxeg, nya, nyag, nye, nyeg,               &
[1551]108                     nza, nze, pos, time_step,                                 &
109                     xa, xe, xxa, xxe, ya, ya_do, ya_tot, ye, ye_do, ye_tot, yya, yye, za,   &
110                     ze, zza, zze
[1]111
[1808]112    INTEGER(8)                        ::  count, count_rate
[493]113
[1394]114    INTEGER(iwp), DIMENSION(0:1)      ::  current_level, current_var,          &
115                                          fanz, id_set, id_var_time, num_var
116    INTEGER(iwp), DIMENSION(4)        ::  id_dims_loc
117    INTEGER(iwp), DIMENSION(0:1,4)    ::  id_dims
118    INTEGER(iwp), DIMENSION(0:1,1000) ::  id_var, levels
[1]119
[1394]120    LOGICAL  ::  avs_output, compressed, found, iso2d_output, netcdf_output,   &
121                 netcdf_parallel, netcdf_0, netcdf_1
[1]122
[1394]123    REAL(wp) ::  cpu_start_time, cpu_end_time, dx, simulated_time
124    REAL(wp),  DIMENSION(:),   ALLOCATABLE   ::  eta, ho, hu
125    REAL(wp),  DIMENSION(:,:), ALLOCATABLE   ::  pf, pf_tmp
[191]126    REAL(spk), DIMENSION(:,:,:), ALLOCATABLE ::  pf3d, pf3d_tmp
[1]127
128    PRINT*, ''
[114]129    PRINT*, ''
[108]130    PRINT*, '*** combine_plot_fields ***'
[114]131
132!
133!-- Find out if a coupled run has been carried out
[108]134    INQUIRE( FILE='COUPLING_PORT_OPENED', EXIST=found )
135    IF ( found )  THEN
136       models = 2
137       PRINT*, '    coupled run'
138    ELSE
139       models = 1
140       PRINT*, '    uncoupled run'
141    ENDIF
[114]142
143!
[691]144!-- Find out if a precursor ocean run has been carried out
145    INQUIRE( FILE='PRECURSOR_OCEAN', EXIST=found )
146    IF ( found )  THEN
147       model_string = '_O'
148       PRINT*, '    precursor ocean run'
149    ELSE
150       model_string = ''
151    ENDIF
152
153!
[114]154!-- Do everything for each model
[108]155    DO model = 1, models
[114]156!
157!--    Set the model string used to identify the filenames
[108]158       IF ( models == 2 )  THEN
159          PRINT*, ''
160          PRINT*, '*** combine_plot_fields ***'
161          IF ( model == 2 )  THEN
[114]162             model_string = '_O'
[108]163             PRINT*, '    now combining ocean data'
164             PRINT*, '    ========================'
165          ELSE
166             PRINT*, '    now combining atmosphere data'
167             PRINT*, '    ============================='
168          ENDIF
169       ENDIF
[1]170!
[108]171!--    2D-arrays for ISO2D
172!--    Main loop for the three different cross-sections, starting with
173!--    xy-section
174       modus = 'XY'
175       PRINT*, ''
176       DO  WHILE ( modus == 'XY'  .OR.  modus == 'XZ'  .OR.  modus == 'YZ' )
[1]177!
[493]178!--       Take current time
179          CALL SYSTEM_CLOCK( count, count_rate )
180          cpu_start_time = REAL( count ) / REAL( count_rate )
181
182          netcdf_parallel = .FALSE.
183!
[108]184!--       Check, if file from PE0 exists. If it does not exist, PALM did not
185!--       create any output for this cross-section.
186          danz = 0
[1468]187          WRITE (id_string,'(I6.6)')  danz
[108]188          INQUIRE ( &
189               FILE='PLOT2D_'//modus//TRIM( model_string )//'_'//id_string, &
190               EXIST=found )
191!
192!--       Find out the number of files (equal to the number of PEs which
193!--       have been used in PALM) and open them
194          DO  WHILE ( found )
[1]195
[108]196             OPEN ( danz+110, &
197                  FILE='PLOT2D_'//modus//TRIM( model_string )//'_'//id_string, &
198                  FORM='UNFORMATTED' )
199             danz = danz + 1
[1468]200             WRITE (id_string,'(I6.6)')  danz
[108]201             INQUIRE ( &
202                  FILE='PLOT2D_'//modus//TRIM( model_string )//'_'//id_string, &
203                  EXIST=found )
[1]204
[108]205          ENDDO
[1]206
207!
[108]208!--       Inquire whether an iso2d parameter file exists
209          INQUIRE( FILE='PLOT2D_'//modus//'_GLOBAL'//TRIM( model_string ), &
210               EXIST=iso2d_output )
[1]211
212!
[108]213!--       Inquire whether a NetCDF file exists
214          INQUIRE( FILE='DATA_2D_'//modus//'_NETCDF'//TRIM( model_string ), &
215               EXIST=netcdf_0 )
[1]216
217!
[108]218!--       Inquire whether a NetCDF file for time-averaged data exists
219          INQUIRE( FILE='DATA_2D_'//modus//'_AV_NETCDF'//TRIM( model_string ),&
220               EXIST=netcdf_1 )
[1]221
[108]222          IF ( netcdf_0  .OR.  netcdf_1 )  THEN
223             netcdf_output = .TRUE.
[493]224!
225!--          Inquire whether the NetCDF file is already complete (parallel
226!--          output)
227             INQUIRE( FILE='NO_COMBINE_PLOT_FIELDS_'//modus, &
228                      EXIST=netcdf_parallel )
229             IF ( netcdf_parallel )  THEN
230                netcdf_parallel = .TRUE.
231             ELSE
232                netcdf_parallel = .FALSE.
233             ENDIF
[108]234          ELSE
235             netcdf_output = .FALSE.
236          ENDIF
[1]237
238!
[108]239!--       Info-output
240          PRINT*, ''
241          PRINT*, '*** combine_plot_fields ***'
[1]242#if defined( __netcdf )
[493]243          IF ( netcdf_output )  THEN
244             IF ( netcdf_parallel )  THEN
245             PRINT*, '    NetCDF ' // modus // '-data are in one file ', &
246                          '(NetCDF4-format) - merging not neccessary'
247             ELSE
248                PRINT*, '    NetCDF output enabled'
249             ENDIF
250          ENDIF
[1]251#else
[108]252          IF ( netcdf_output )  THEN
253             PRINT*, '--- Sorry, no NetCDF support on this host'
254             netcdf_output = .FALSE.
255          ENDIF
[1]256#endif
[493]257          IF ( .NOT. netcdf_parallel )  THEN
258             IF ( danz /= 0 )  THEN
259                PRINT*, '    ',modus,'-section:  ', danz, ' file(s) found'
260             ELSE
261                PRINT*, '    no ', modus, '-section data available'
262             ENDIF
[108]263          ENDIF
[1]264
[493]265          IF ( netcdf_output  .AND. .NOT. netcdf_parallel  .AND.  danz /= 0 ) &
266          THEN
[1]267#if defined( __netcdf )
[108]268             DO  av = 0, 1
[1]269
[108]270                IF ( av == 0  .AND.  .NOT.  netcdf_0 )  CYCLE
271                IF ( av == 1  .AND.  .NOT.  netcdf_1 )  CYCLE
[1]272
273!
[108]274!--             Open NetCDF dataset
275                IF ( av == 0 )  THEN
276                   filename = 'DATA_2D_'//modus//'_NETCDF' &
277                        //TRIM( model_string )
278                ELSE
279                   filename = 'DATA_2D_'//modus//'_AV_NETCDF' &
280                        //TRIM( model_string )
281                ENDIF
282                nc_stat = NF90_OPEN( filename, NF90_WRITE, id_set(av) )
283                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 1 )
[1]284
285!
[108]286!--             Get the list of variables (order of variables corresponds with
287!--             the order of data on the binary file)
288                var_list(av) = ' '    ! GET_ATT does not assign trailing blanks
289                nc_stat = NF90_GET_ATT( id_set(av), NF90_GLOBAL, 'VAR_LIST', &
290                     var_list(av) )
291                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 2 )
[1]292
293!
[108]294!--             Inquire id of the time coordinate variable
295                nc_stat = NF90_INQ_VARID( id_set(av), 'time', id_var_time(av) )
296                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 3 )
[1]297
298!
[108]299!--             Count number of variables; there is one more semicolon in the
300!--             string than variable names
301                num_var(av) = -1
302                DO  i = 1, LEN( var_list(av) )
303                   IF ( var_list(av)(i:i) == ';' )  num_var(av) = num_var(av) +1
304                ENDDO
[1]305
306!
[108]307!--             Extract the variable names from the list and inquire their
308!--             NetCDF IDs
309                pos = INDEX( var_list(av), ';' )
[1]310!
[108]311!--             Loop over all variables
312                DO  i = 1, num_var(av)
[1]313
314!
[108]315!--                Extract variable name from list
316                   var_list(av) = var_list(av)(pos+1:)
317                   pos = INDEX( var_list(av), ';' )
318                   var_name = var_list(av)(1:pos-1)
[1]319
320!
[108]321!--                Get variable ID from name
322                   nc_stat = NF90_INQ_VARID( id_set(av), TRIM( var_name ), &
323                        id_var(av,i) )
324                   IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 4 )
[1]325
326!
[108]327!--                Get number of x/y/z levels for that variable
328                   nc_stat = NF90_INQUIRE_VARIABLE( id_set(av), id_var(av,i), &
329                        dimids = id_dims_loc )
330                   IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 5 )
331                   id_dims(av,:) = id_dims_loc
[1]332
333!
[108]334!--                Inquire dimension ID
335                   DO  j = 1, 4
336                      nc_stat = NF90_INQUIRE_DIMENSION( id_set(av), &
337                           id_dims(av,j), dimname, levels(av,i) )
338                      IF ( nc_stat /= NF90_NOERR ) CALL handle_netcdf_error( 6 )
[1]339
[108]340                      IF ( modus == 'XY' .AND. INDEX(dimname, 'z') /= 0 )  EXIT
341                      IF ( modus == 'XZ' .AND. INDEX(dimname, 'y') /= 0 )  EXIT
342                      IF ( modus == 'YZ' .AND. INDEX(dimname, 'x') /= 0 )  EXIT
343                   ENDDO
344
[1]345                ENDDO
346
[108]347             ENDDO   ! av = 0, 1
[1]348
[179]349#endif
[108]350          ENDIF
[1]351
352!
[108]353!--       Read the arrays, as long as the end of the file is reached
[493]354          IF ( .NOT. netcdf_parallel )  THEN
[1]355
[493]356             fanz          =         0
357             current_level =         1
358             current_var   = 999999999
[1]359
[493]360             DO  WHILE ( danz /= 0 )
361
[1]362!
[493]363!--             Loop over all files (reading data of the subdomains)
364                DO  id = 0, danz-1
[1]365!
[493]366!--                File from PE0 contains special information at the beginning,
367!--                concerning the lower and upper indices of the total-domain
368!--                used in PALM (nxag, nxeg, nyag, nyeg) and the lower and
[1551]369!--                upper indices of the array to be written by this routine
[493]370!--                (nxa, nxe, nya, nye). Usually in the horizontal directions
371!--                nxag=-1 and nxa=0 while all other variables have the same
372!--                value (i.e. nxeg=nxe).
373!--                Allocate necessary arrays, open the output file and write
374!--                the coordinate informations needed by ISO2D.
375                   IF ( id == 0  .AND.  fanz(0) == 0  .AND.  fanz(1) == 0 ) THEN
376                      READ ( id+110 )  nxag, nxeg, nyag, nyeg
377                      READ ( id+110 )  nxa, nxe, nya, nye
378                      ALLOCATE ( eta(nya:nye), ho(nxa:nxe), hu(nxa:nxe), &
379                                 pf(nxag:nxeg,nyag:nyeg) )
380                      READ ( id+110 )  dx, eta, hu, ho
[1]381
[1551]382
383!
384!--                   Set actual domain bounds to total domain
385                      ya_do = nya
386                      ye_do = nye
387
[493]388                      IF ( iso2d_output )  THEN
389                         OPEN ( 2, FILE='PLOT2D_'//modus//TRIM( model_string ),&
390                                   FORM='UNFORMATTED' )
391                         WRITE ( 2 )  dx, eta, hu, ho
392                      ENDIF
[108]393                   ENDIF
[1]394!
[493]395!--                Read output time
396                   IF ( netcdf_output  .AND.  id == 0 )  THEN
397                      IF ( netcdf_1 )  THEN
398                         READ ( id+110, END=998 )  simulated_time, time_step, av
399                      ELSE
[1]400!
[493]401!--                      For compatibility with earlier PALM versions
402                         READ ( id+110, END=998 )  simulated_time, time_step
403                         av = 0
404                      ENDIF
[108]405                   ENDIF
[1]406!
[493]407!--                Read subdomain indices
[1551]408                   READ ( id+110, END=998 )  xa, xe, ya, ye, ya_tot, ye_tot
409
[1]410!
[493]411!--                IF the PE made no output (in case that no part of the
412!--                cross-section is situated on this PE), indices have the
413!--                value -1
414                   IF ( .NOT. ( xa == -1  .AND.  xe == -1  .AND. &
415                                ya == -1  .AND.  ye == -1 ) )  THEN
[1551]416
417
[1]418!
[493]419!--                   Read the subdomain grid-point values
420                      ALLOCATE( pf_tmp(xa:xe,ya:ye) )
421                      READ ( id+110 )  pf_tmp
[1551]422!
423!--                   Calculate indices on atmospheric grid (e.g. for soil model
424!--                   quantities)
425                      IF ( ya /= ya_tot .OR. ye /= ye_tot )  THEN
426                         ye_do = ye - ya
427                         ya_do = ya
428                         pf(xa:xe,ya_do:ye_do) = pf_tmp
429                      ELSE
430                         ye_do = nye
431                         ya_do = nya
432                         pf(xa:xe,ya:ye) = pf_tmp
433                      ENDIF
434
[493]435                      DEALLOCATE( pf_tmp )
436                   ENDIF
437                   IF ( id == 0 )  fanz(av) = fanz(av) + 1
[1]438
[493]439                ENDDO
[1]440!
[493]441!--             Write the data of the total domain cross-section
442                IF ( iso2d_output )  WRITE ( 2 )  pf(nxa:nxe,nya:nye)
[1]443       
444!
[493]445!--             Write same data in NetCDF format
446                IF ( netcdf_output )  THEN
[1]447#if defined( __netcdf )
448!
[493]449!--                Check if a new time step has begun; if yes write data to
450!--                time axis
451                   IF ( current_var(av) > num_var(av) )  THEN
452                      current_var(av) = 1
453                      nc_stat = NF90_PUT_VAR( id_set(av), id_var_time(av), &
454                                              (/ simulated_time /),        &
455                                              start = (/ time_step /),     &
456                                              count = (/ 1 /) )
457                      IF ( nc_stat /= NF90_NOERR ) CALL handle_netcdf_error( 7 )
458                   ENDIF
[1]459
460!
[493]461!--                Now write the data; this is mode dependent
462                   SELECT CASE ( modus )
[1]463
[493]464                      CASE ( 'XY' )
465                         nc_stat = NF90_PUT_VAR( id_set(av),                   &
[1]466                                           id_var(av,current_var(av)),         &
467                                           pf(nxa:nxe,nya:nye),                &
468                             start = (/ 1, 1, current_level(av), time_step /), &
469                                      count = (/ nxe-nxa+1, nye-nya+1, 1, 1 /) )
[493]470                         IF ( nc_stat /= NF90_NOERR )  THEN
471                            CALL handle_netcdf_error( 8 )
472                         ENDIF
[1]473                 
[493]474                      CASE ( 'XZ' )
475                         nc_stat = NF90_PUT_VAR( id_set(av),                   &
[1]476                                           id_var(av,current_var(av)),         &
[1551]477                                           pf(nxa:nxe,ya_do:ye_do),            &
[1]478                             start = (/ 1, current_level(av), 1, time_step /), &
[1551]479                                      count = (/ nxe-nxa+1, 1, ye_do-ya_do+1, 1 /) )
[493]480                         IF ( nc_stat /= NF90_NOERR )  THEN
481                            CALL handle_netcdf_error( 9 )
482                         ENDIF
[1]483
[493]484                      CASE ( 'YZ' )
485                         nc_stat = NF90_PUT_VAR( id_set(av),                   &
[1]486                                           id_var(av,current_var(av)),         &
[1551]487                                           pf(nxa:nxe,ya_do:ye_do),            &
[1]488                             start = (/ current_level(av), 1, 1, time_step /), &
[1551]489                                      count = (/ 1, nxe-nxa+1, ye_do-ya_do+1, 1 /) )
[493]490                         IF ( nc_stat /= NF90_NOERR )  THEN
491                            CALL handle_netcdf_error( 10 )
492                         ENDIF
[1]493
[493]494                   END SELECT
[1]495
496!
[493]497!--                Data is written, check if max level is reached
498                   current_level(av) = current_level(av) + 1
499                   IF ( current_level(av) > levels(av,current_var(av)) )  THEN
500                      current_level(av) = 1
501                      current_var(av)   = current_var(av) + 1
502                   ENDIF
[108]503
[179]504#endif
[493]505                ENDIF
[1]506
[493]507             ENDDO
[1]508
[493]509          ENDIF
510
511998       IF ( danz /= 0  .AND.  .NOT. netcdf_parallel )  THEN
[1]512!
[108]513!--          Print the number of the arrays processed
514             WRITE (*,'(16X,I4,A)')  fanz(0)+fanz(1), ' array(s) processed'
515             IF ( fanz(1) /= 0 )  THEN
516                WRITE (*,'(16X,I4,A)')  fanz(1), ' array(s) are time-averaged'
517             ENDIF
[1]518
519!
[108]520!--          Close all files and deallocate arrays
521             DO  id = 0, danz-1
522                CLOSE ( id+110 )
523             ENDDO
524             CLOSE ( 2 )
525             DEALLOCATE ( eta, ho, hu, pf )
[1]526
527!
[493]528!--          Close the NetCDF file
529             IF ( netcdf_output )  THEN
[1]530#if defined( __netcdf )
[493]531                IF ( netcdf_0 )  THEN
532                   nc_stat = NF90_CLOSE( id_set(0) )
533                   IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 11 )
534                ENDIF
535                IF ( netcdf_1 )  THEN
536                   nc_stat = NF90_CLOSE( id_set(1) )
537                   IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 12 )
538                ENDIF
539#endif
[108]540             ENDIF
[493]541          ENDIF
542
543!
544!--       Output required cpu time
545          IF ( danz /= 0  .AND.  .NOT. netcdf_parallel )  THEN
546             CALL SYSTEM_CLOCK( count, count_rate )
547             cpu_end_time = REAL( count ) / REAL( count_rate )
548             WRITE (*,'(5X,A,F9.3,A)')  'Required cpu-time: ', &
549                                        cpu_end_time-cpu_start_time, ' sec'
[1]550          ENDIF
551
552!
[108]553!--       Choose the next cross-section
554          SELECT CASE ( modus )
555             CASE ( 'XY' )
556                modus = 'XZ'
557             CASE ( 'XZ' )
558                modus = 'YZ'
559             CASE ( 'YZ' )
560                modus = 'no'
561          END SELECT
[1]562
[108]563       ENDDO
[1]564
565
566!
[108]567!--    Combine the 3D-arrays
[493]568       netcdf_parallel = .FALSE.
[1]569
570!
[493]571!--    Info-output
572       PRINT*, ' '
573       PRINT*, '*** combine_plot_fields ***'
574
575!
576!--    Take current time
577       CALL SYSTEM_CLOCK( count, count_rate )
578       cpu_start_time = REAL( count ) / REAL( count_rate )
579
580!
[108]581!--    Inquire whether an avs fld file exists
582       INQUIRE( FILE='PLOT3D_FLD'//TRIM( model_string ), EXIST=avs_output )
[1]583
584!
[108]585!--    Inquire whether a NetCDF file exists
586       INQUIRE( FILE='DATA_3D_NETCDF'//TRIM( model_string ), EXIST=netcdf_0 )
[1]587
588!
[108]589!--    Inquire whether a NetCDF file for time-averaged data exists
590       INQUIRE( FILE='DATA_3D_AV_NETCDF'//TRIM( model_string ), EXIST=netcdf_1 )
[1]591
[108]592       IF ( netcdf_0  .OR.  netcdf_1 )  THEN
593          netcdf_output = .TRUE.
[493]594!
595!--       Inquire whether the NetCDF file is already complete (parallel output)
596          INQUIRE( FILE='NO_COMBINE_PLOT_FIELDS_3D', EXIST=netcdf_parallel )
597          IF ( netcdf_parallel )  THEN
598             netcdf_parallel = .TRUE.
599          ELSE
600             netcdf_parallel = .FALSE.
601          ENDIF
[108]602       ELSE
603          netcdf_output = .FALSE.
604       ENDIF
[1]605
606!
[493]607!--    Check, if file from PE0 exists; not neccessary in case of parallel
608!--    PALM output
609       IF ( .NOT. netcdf_parallel )  THEN
610          danz = 0
[1468]611          WRITE (id_string,'(I6.6)')  danz
[493]612          INQUIRE ( &
613               FILE='PLOT3D_DATA'//TRIM( model_string )//'_'//TRIM( id_string ),  &
614               EXIST=found )
615       ELSE
616          found = .FALSE.
617       ENDIF
[1]618
619!
[108]620!--    Combination only works, if data are not compressed. In that case,
621!--    PALM created a flag file (PLOT3D_COMPRESSED)
622       INQUIRE ( FILE='PLOT3D_COMPRESSED'//TRIM( model_string ), &
623            EXIST=compressed )
[1]624
625!
[108]626!--    Find out the number of files and open them
627       DO  WHILE ( found  .AND.  .NOT. compressed )
[1]628
[108]629          OPEN ( danz+110, &
630               FILE='PLOT3D_DATA'//TRIM( model_string )//'_'//TRIM(id_string), &
631               FORM='UNFORMATTED')
632          danz = danz + 1
[1468]633          WRITE (id_string,'(I6.6)')  danz
[108]634          INQUIRE ( &
635               FILE='PLOT3D_DATA'//TRIM( model_string )//'_'//TRIM(id_string), &
636               EXIST=found )
[1]637
[108]638       ENDDO
[1]639
640#if defined( __netcdf )
[493]641       IF ( netcdf_output )  THEN
642          IF ( netcdf_parallel )  THEN
643             PRINT*, '    NetCDF data are in one file (NetCDF4-format)', &
644                          ' - merging not neccessary'
645          ELSE
646             PRINT*, '    NetCDF output enabled'
647          ENDIF
648       ENDIF
[1]649#else
650       IF ( netcdf_output )  THEN
651          PRINT*, '--- Sorry, no NetCDF support on this host'
652          netcdf_output = .FALSE.
653       ENDIF
654#endif
[493]655       IF ( .NOT. netcdf_parallel )  THEN
656          IF ( danz /= 0 )  THEN
657             PRINT*, '    3D-data:     ', danz, ' file(s) found'
[108]658          ELSE
[493]659             IF ( found .AND. compressed )  THEN
660                PRINT*, '+++ no 3D-data processing, since data are compressed'
661             ELSE
662                PRINT*, '    no 3D-data file available'
663             ENDIF
[108]664          ENDIF
[1]665       ENDIF
666
[493]667       IF ( netcdf_output  .AND. .NOT. netcdf_parallel  .AND.  danz /= 0 )  THEN
[1]668#if defined( __netcdf )
[108]669          DO  av = 0, 1
[1]670
[108]671             IF ( av == 0  .AND.  .NOT.  netcdf_0 )  CYCLE
672             IF ( av == 1  .AND.  .NOT.  netcdf_1 )  CYCLE
[1]673
674!
[108]675!--          Open NetCDF dataset
676             IF ( av == 0 )  THEN
677                filename = 'DATA_3D_NETCDF'//TRIM( model_string )
678             ELSE
679                filename = 'DATA_3D_AV_NETCDF'//TRIM( model_string )
680             ENDIF
681             nc_stat = NF90_OPEN( filename, NF90_WRITE, id_set(av) )
682             IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 13 )
[1]683
684
685!
[108]686!--          Get the list of variables (order of variables corresponds with the
687!--          order of data on the binary file)
688             var_list(av) = ' '    ! GET_ATT does not assign trailing blanks
689             nc_stat = NF90_GET_ATT( id_set(av), NF90_GLOBAL, 'VAR_LIST', &
690                  var_list(av) )
691             IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 14 )
[1]692
693!
[108]694!--          Inquire id of the time coordinate variable
695             nc_stat = NF90_INQ_VARID( id_set(av), 'time', id_var_time(av) )
696             IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 15 )
[1]697
698!
[108]699!--          Count number of variables; there is one more semicolon in the
700!--          string than variable names
701             num_var(av) = -1
702             DO  i = 1, LEN( var_list(av) )
703                IF ( var_list(av)(i:i) == ';' )  num_var(av) = num_var(av) + 1
704             ENDDO
[1]705
706!
[108]707!--          Extract the variable names from the list and inquire their NetCDF
708!--          IDs
709             pos = INDEX( var_list(av), ';' )
[1]710!
[108]711!--          Loop over all variables
712             DO  i = 1, num_var(av)
[1]713
714!
[108]715!--             Extract variable name from list
716                var_list(av) = var_list(av)(pos+1:)
717                pos = INDEX( var_list(av), ';' )
718                var_name = var_list(av)(1:pos-1)
[1]719
720!
[108]721!--             Get variable ID from name
722                nc_stat = NF90_INQ_VARID( id_set(av), TRIM( var_name ), &
723                     id_var(av,i) )
724                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 16 )
[1]725
[108]726             ENDDO
[1]727
[108]728          ENDDO    ! av=0,1
[1]729
[179]730#endif
[108]731       ENDIF
[1]732
733!
[108]734!--    Read arrays, until the end of the file is reached
[493]735       IF ( .NOT. netcdf_parallel )  THEN
[1]736
[493]737          current_var = 999999999
738          fanz = 0
739          DO  WHILE ( danz /= 0 )
740
[1]741!
[493]742!--          Loop over all files
743             DO  id = 0, danz-1
[1]744!
[493]745!--             File from PE0 contains special information at the beginning,
746!--             concerning the lower and upper indices of the total-domain used
[1551]747!--             in PALM (nxag, nxeg, nyag, nyeg) and the lower and
[493]748!--             upper indices of the array to be written by this routine (nxa,
749!--             nxe, nya, nye, nza, nze). Usually nxag=-1 and nxa=0, nyag=-1
[1551]750!--             and nya=0, nzeg=nz and nze=nz_do3d.
[493]751!--             Allocate necessary array and open the output file.
752                IF ( id == 0  .AND.  fanz(0) == 0  .AND.  fanz(1) == 0 )  THEN
[1551]753                   READ ( id+110 )  nxag, nxeg, nyag, nyeg
[493]754                   READ ( id+110 )  nxa, nxe, nya, nye, nza, nze
755                   ALLOCATE ( pf3d(nxa:nxe,nya:nye,nza:nze) )
756                   IF ( avs_output )  THEN
757                      OPEN ( 2, FILE='PLOT3D_DATA'//TRIM( model_string ), &
758                             FORM='UNFORMATTED' )
759                   ENDIF
[108]760                ENDIF
[1]761
762!
[493]763!--             Read output time
764                IF ( netcdf_output  .AND.  id == 0 )  THEN
765                   IF ( netcdf_1 )  THEN
766                      READ ( id+110, END=999 )  simulated_time, time_step, av
767                   ELSE
[1]768!
[493]769!--                   For compatibility with earlier PALM versions
770                      READ ( id+110, END=999 )  simulated_time, time_step
771                      av = 0
772                   ENDIF
[108]773                ENDIF
[1]774
775!
[493]776!--             Read subdomain indices and grid point values
777                READ ( id+110, END=999 )  xa, xe, ya, ye, za, ze
778                ALLOCATE( pf3d_tmp(xa:xe,ya:ye,za:ze) )
779                READ ( id+110 )  pf3d_tmp
[210]780
[493]781                xxa = MAX( nxa, xa )
782                xxe = MIN( nxe, xe )
783                yya = MAX( nya, ya )
784                yye = MIN( nye, ye )
[1551]785                DO  k = za, ze
[493]786                   DO  j = yya, yye
787                      DO  i = xxa, xxe
788                         pf3d(i,j,k) = pf3d_tmp(i,j,k)
789                      ENDDO
[210]790                   ENDDO
791                ENDDO
792
[493]793                DEALLOCATE( pf3d_tmp )
794                IF ( id == 0 )  fanz(av) = fanz(av) + 1
[1]795
[493]796             ENDDO
[1]797
798!
[493]799!--          Write data of the total domain
800             IF ( avs_output )  WRITE ( 2 )  pf3d(nxa:nxe,nya:nye,nza:nze)
[1]801       
802!
[493]803!--          Write same data in NetCDF format
804             IF ( netcdf_output )  THEN
[1]805#if defined( __netcdf )
806!
[493]807!--             Check if a new time step has begun; if yes write data to time
808!--             axis
809                IF ( current_var(av) > num_var(av) )  THEN
810                   current_var(av) = 1
811                   nc_stat = NF90_PUT_VAR( id_set(av), id_var_time(av), &
812                                      (/ simulated_time /),&
813                                      start = (/ time_step /), count = (/ 1 /) )
814                   IF ( nc_stat /= NF90_NOERR ) CALL handle_netcdf_error( 17 )
815                ENDIF
[1]816
817!
[493]818!--             Now write the data
819                nc_stat = NF90_PUT_VAR( id_set(av), id_var(av,current_var(av)),&
[1551]820                                        pf3d(nxa:nxe,nya:nye,za:ze), start = (/ 1, 1, 1, time_step /),&
821                              count = (/ nxe-nxa+1, nye-nya+1, ze-za+1, 1 /) )
[493]822                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 18 )
[1]823
[493]824                current_var(av) = current_var(av) + 1
[1]825
826#endif
[493]827             ENDIF
[1]828
[493]829          ENDDO
[1]830
[493]831       ENDIF
832
833999    IF ( danz /= 0  .AND.  .NOT. netcdf_parallel )  THEN
[1]834!
[108]835!--       Print the number of arrays processed
836          WRITE (*,'(16X,I4,A)')  fanz(0)+fanz(1), ' array(s) processed'
837          IF ( fanz(1) /= 0 )  THEN
838             WRITE (*,'(16X,I4,A)')  fanz(1), ' array(s) are time-averaged'
839          ENDIF
[1]840!
[108]841!--       Close all files and deallocate array
842          DO  id = 0, danz-1
843             CLOSE ( id+110 )
844          ENDDO
845          CLOSE ( 2 )
846          DEALLOCATE ( pf3d )
[1]847!
[108]848!--       Close the NetCDF file
849          IF ( netcdf_output )  THEN
[1]850#if defined( __netcdf )
[108]851             IF ( netcdf_0 )  THEN
852                nc_stat = NF90_CLOSE( id_set(0) )
853                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 19 )
854             ENDIF
855             IF ( netcdf_1 )  THEN
856                nc_stat = NF90_CLOSE( id_set(1) )
857                IF ( nc_stat /= NF90_NOERR )  CALL handle_netcdf_error( 20 )
858             ENDIF
859#endif
[1]860          ENDIF
[493]861
862!
863!--       Output required cpu time
864          CALL SYSTEM_CLOCK( count, count_rate )
865          cpu_end_time = REAL( count ) / REAL( count_rate )
866          WRITE (*,'(5X,A,F9.3,A)')  'Required cpu-time: ', &
867                                     cpu_end_time-cpu_start_time, ' sec'
868
[1]869       ENDIF
870
[108]871    ENDDO  ! models
[1]872
[108]873
[1]874 CONTAINS
875
876
877    SUBROUTINE handle_netcdf_error( errno )
878!
879!--    Prints out a text message corresponding to the current NetCDF status
880
881       IMPLICIT NONE
882
883       INTEGER, INTENT(IN) ::  errno
884
[179]885#if defined( __netcdf )
[1]886       IF ( nc_stat /= NF90_NOERR )  THEN
887          PRINT*, '+++ combine_plot_fields  netcdf: ', av, errno, &
888                  TRIM( nf90_strerror( nc_stat ) )
889       ENDIF
[179]890#endif
[1]891
892    END SUBROUTINE handle_netcdf_error
893
894
895 END PROGRAM combine_plot_fields
896
897
898
Note: See TracBrowser for help on using the repository browser.