source: palm/trunk/SOURCE/data_output_3d.f90 @ 1053

Last change on this file since 1053 was 1053, checked in by hoffmann, 11 years ago

two-moment cloud physics implemented

  • Property svn:keywords set to Id
File size: 20.6 KB
Line 
1 SUBROUTINE data_output_3d( av )
2
3!--------------------------------------------------------------------------------!
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!
17! Copyright 1997-2012  Leibniz University Hannover
18!--------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22! +nr, qr, prr, qc and averaged quantities
23!
24! Former revisions:
25! -----------------
26! $Id: data_output_3d.f90 1053 2012-11-13 17:11:03Z hoffmann $
27!
28! 1036 2012-10-22 13:43:42Z raasch
29! code put under GPL (PALM 3.9)
30!
31! 1031 2012-10-19 14:35:30Z raasch
32! netCDF4 without parallel file support implemented
33!
34! 1007 2012-09-19 14:30:36Z franke
35! Bugfix: missing calculation of ql_vp added
36!
37! 790 2011-11-29 03:11:20Z raasch
38! bugfix: calculation of 'pr' must depend on the particle weighting factor,
39! nzt+1 replaced by nz_do3d for 'pr'
40!
41! 771 2011-10-27 10:56:21Z heinze
42! +lpt
43!
44! 759 2011-09-15 13:58:31Z raasch
45! Splitting of parallel I/O
46!
47! 727 2011-04-20 20:05:25Z suehring
48! Exchange ghost layers also for p_av.
49!
50! 725 2011-04-11 09:37:01Z suehring
51! Exchange ghost layers for p regardless of used pressure solver (except SOR).
52!
53! 691 2011-03-04 08:45:30Z maronga
54! Replaced simulated_time by time_since_reference_point
55!
56! 673 2011-01-18 16:19:48Z suehring
57! When using Multigrid or SOR solver an additional CALL exchange_horiz is
58! is needed for pressure output.
59!
60! 667 2010-12-23 12:06:00Z suehring/gryschka
61! nxl-1, nxr+1, nys-1, nyn+1 replaced by nxlg, nxrg, nysg, nyng in loops and
62! allocation of arrays.  Calls of exchange_horiz are modified.
63! Skip-value skip_do_avs changed to a dynamic adaption of ghost points.
64!
65! 646 2010-12-15 13:03:52Z raasch
66! bugfix: missing define statements for netcdf added
67!
68! 493 2010-03-01 08:30:24Z raasch
69! netCDF4 support (parallel output)
70!
71! 355 2009-07-17 01:03:01Z letzel
72! simulated_time in netCDF output replaced by time_since_reference_point.
73! Output of netCDF messages with aid of message handling routine.
74! Output of messages replaced by message handling routine.
75! Bugfix: to_be_resorted => s_av for time-averaged scalars
76!
77! 96 2007-06-04 08:07:41Z raasch
78! Output of density and salinity
79!
80! 75 2007-03-22 09:54:05Z raasch
81! 2nd+3rd argument removed from exchange horiz
82!
83! RCS Log replace by Id keyword, revision history cleaned up
84!
85! Revision 1.3  2006/06/02 15:18:59  raasch
86! +argument "found", -argument grid in call of routine user_data_output_3d
87!
88! Revision 1.2  2006/02/23 10:23:07  raasch
89! Former subroutine plot_3d renamed data_output_3d, pl.. renamed do..,
90! .._anz renamed .._n,
91! output extended to (almost) all quantities, output of user-defined quantities
92!
93! Revision 1.1  1997/09/03 06:29:36  raasch
94! Initial revision
95!
96!
97! Description:
98! ------------
99! Output of the 3D-arrays in netCDF and/or AVS format.
100!------------------------------------------------------------------------------!
101
102    USE array_kind
103    USE arrays_3d
104    USE averaging
105    USE cloud_parameters
106    USE control_parameters
107    USE cpulog
108    USE indices
109    USE interfaces
110    USE netcdf_control
111    USE particle_attributes
112    USE pegrid
113
114    IMPLICIT NONE
115
116    CHARACTER (LEN=9) ::  simulated_time_mod
117
118    INTEGER           ::  av, i, if, j, k, n, pos, prec, psi
119
120    LOGICAL           ::  found, resorted
121
122    REAL              ::  mean_r, s_r3, s_r4
123
124    REAL(spk), DIMENSION(:,:,:), ALLOCATABLE  ::  local_pf
125
126    REAL, DIMENSION(:,:,:), POINTER ::  to_be_resorted
127
128!
129!-- Return, if nothing to output
130    IF ( do3d_no(av) == 0 )  RETURN
131
132    CALL cpu_log (log_point(14),'data_output_3d','start')
133
134!
135!-- Open output file.
136!-- Also creates coordinate and fld-file for AVS.
137!-- For classic or 64bit netCDF output or output of other (old) data formats,
138!-- for a run on more than one PE, each PE opens its own file and
139!-- writes the data of its subdomain in binary format (regardless of the format
140!-- the user has requested). After the run, these files are combined to one
141!-- file by combine_plot_fields in the format requested by the user (netcdf
142!-- and/or avs).
143!-- For netCDF4/HDF5 output, data is written in parallel into one file.
144    IF ( netcdf_output )  THEN
145       IF ( netcdf_data_format < 5 )  THEN
146          CALL check_open( 30 )
147          IF ( myid == 0 )  CALL check_open( 106+av*10 )
148       ELSE
149          CALL check_open( 106+av*10 )
150       ENDIF
151    ELSE
152       IF ( avs_output  .OR.  ( numprocs > 1 ) )  CALL check_open( 30 )
153    ENDIF
154
155!
156!-- Allocate a temporary array with the desired output dimensions.
157    ALLOCATE( local_pf(nxlg:nxrg,nysg:nyng,nzb:nz_do3d) )
158
159!
160!-- Update the netCDF time axis
161#if defined( __netcdf )
162    IF ( myid == 0  .OR.  netcdf_data_format > 4 )  THEN
163       do3d_time_count(av) = do3d_time_count(av) + 1
164       IF ( netcdf_output )  THEN
165          nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_time_3d(av), &
166                                  (/ time_since_reference_point /),  &
167                                  start = (/ do3d_time_count(av) /), &
168                                  count = (/ 1 /) )
169          CALL handle_netcdf_error( 'data_output_3d', 376 )
170       ENDIF
171    ENDIF
172#endif
173
174!
175!-- Loop over all variables to be written.
176    if = 1
177
178    DO  WHILE ( do3d(av,if)(1:1) /= ' ' )
179!
180!--    Set the precision for data compression.
181       IF ( do3d_compress )  THEN
182          DO  i = 1, 100
183             IF ( plot_3d_precision(i)%variable == do3d(av,if) )  THEN
184                prec = plot_3d_precision(i)%precision
185                EXIT
186             ENDIF
187          ENDDO
188       ENDIF
189
190!
191!--    Store the array chosen on the temporary array.
192       resorted = .FALSE.
193       SELECT CASE ( TRIM( do3d(av,if) ) )
194
195          CASE ( 'e' )
196             IF ( av == 0 )  THEN
197                to_be_resorted => e
198             ELSE
199                to_be_resorted => e_av
200             ENDIF
201
202          CASE ( 'lpt' )
203             IF ( av == 0 )  THEN
204                to_be_resorted => pt
205             ELSE
206                to_be_resorted => lpt_av
207             ENDIF
208
209          CASE ( 'nr' )
210             IF ( av == 0 )  THEN
211                to_be_resorted => nr
212             ELSE
213                to_be_resorted => nr_av
214             ENDIF
215
216          CASE ( 'p' )
217             IF ( av == 0 )  THEN
218                IF ( psolver /= 'sor' )  CALL exchange_horiz( p, nbgp )
219                to_be_resorted => p
220             ELSE
221                IF ( psolver /= 'sor' )  CALL exchange_horiz( p_av, nbgp )
222                to_be_resorted => p_av
223             ENDIF
224
225          CASE ( 'pc' )  ! particle concentration (requires ghostpoint exchange)
226             IF ( av == 0 )  THEN
227                tend = prt_count
228                CALL exchange_horiz( tend, nbgp )
229                DO  i = nxlg, nxrg
230                   DO  j = nysg, nyng
231                      DO  k = nzb, nz_do3d
232                         local_pf(i,j,k) = tend(k,j,i)
233                      ENDDO
234                   ENDDO
235                ENDDO
236                resorted = .TRUE.
237             ELSE
238                CALL exchange_horiz( pc_av, nbgp )
239                to_be_resorted => pc_av
240             ENDIF
241
242          CASE ( 'pr' )  ! mean particle radius
243             IF ( av == 0 )  THEN
244                DO  i = nxl, nxr
245                   DO  j = nys, nyn
246                      DO  k = nzb, nz_do3d
247                         psi = prt_start_index(k,j,i)
248                         s_r3 = 0.0
249                         s_r4 = 0.0
250                         DO  n = psi, psi+prt_count(k,j,i)-1
251                         s_r3 = s_r3 + particles(n)%radius**3 * &
252                                       particles(n)%weight_factor
253                         s_r4 = s_r4 + particles(n)%radius**4 * &
254                                       particles(n)%weight_factor
255                         ENDDO
256                         IF ( s_r3 /= 0.0 )  THEN
257                            mean_r = s_r4 / s_r3
258                         ELSE
259                            mean_r = 0.0
260                         ENDIF
261                         tend(k,j,i) = mean_r
262                      ENDDO
263                   ENDDO
264                ENDDO
265                CALL exchange_horiz( tend, nbgp )
266                DO  i = nxlg, nxrg
267                   DO  j = nysg, nyng
268                      DO  k = nzb, nz_do3d
269                         local_pf(i,j,k) = tend(k,j,i)
270                      ENDDO
271                   ENDDO
272                ENDDO
273                resorted = .TRUE.
274             ELSE
275                CALL exchange_horiz( pr_av, nbgp )
276                to_be_resorted => pr_av
277             ENDIF
278
279          CASE ( 'prr' )
280             IF ( av == 0 )  THEN
281                CALL exchange_horiz( prr, nbgp )
282                DO  i = nxlg, nxrg
283                   DO  j = nysg, nyng
284                      DO  k = nzb, nzt+1
285                         local_pf(i,j,k) = prr(k,j,i)
286                      ENDDO
287                   ENDDO
288                ENDDO
289             ELSE
290                CALL exchange_horiz( prr_av, nbgp )
291                DO  i = nxlg, nxrg
292                   DO  j = nysg, nyng
293                      DO  k = nzb, nzt+1
294                         local_pf(i,j,k) = prr_av(k,j,i)
295                      ENDDO
296                   ENDDO
297                ENDDO
298             ENDIF
299             resorted = .TRUE.
300
301          CASE ( 'pt' )
302             IF ( av == 0 )  THEN
303                IF ( .NOT. cloud_physics ) THEN
304                   to_be_resorted => pt
305                ELSE
306                   DO  i = nxlg, nxrg
307                      DO  j = nysg, nyng
308                         DO  k = nzb, nz_do3d
309                            local_pf(i,j,k) = pt(k,j,i) + l_d_cp *    &
310                                                          pt_d_t(k) * &
311                                                          ql(k,j,i)
312                         ENDDO
313                      ENDDO
314                   ENDDO
315                   resorted = .TRUE.
316                ENDIF
317             ELSE
318                to_be_resorted => pt_av
319             ENDIF
320
321          CASE ( 'q' )
322             IF ( av == 0 )  THEN
323                to_be_resorted => q
324             ELSE
325                to_be_resorted => q_av
326             ENDIF
327
328          CASE ( 'qc' )
329             IF ( av == 0 )  THEN
330                to_be_resorted => ql
331             ELSE
332                to_be_resorted => ql_av
333             ENDIF
334
335          CASE ( 'ql' )
336             IF ( av == 0 )  THEN
337                IF ( icloud_scheme == 0 )  THEN
338                   DO  i = nxlg, nxrg
339                      DO  j = nysg, nyng
340                         DO  k = nzb, nz_do3d
341                            local_pf(i,j,k) = ql(k,j,i) + qr(k,j,i)
342                         ENDDO
343                      ENDDO
344                   ENDDO
345                   resorted = .TRUE.
346                ELSE
347                   to_be_resorted => ql
348                ENDIF
349             ELSE
350                IF ( icloud_scheme == 0 )  THEN
351                   DO  i = nxlg, nxrg
352                      DO  j = nysg, nyng
353                         DO  k = nzb, nz_do3d
354                            local_pf(i,j,k) = ql_av(k,j,i) + qr_av(k,j,i)
355                         ENDDO
356                      ENDDO
357                   ENDDO
358                   resorted = .TRUE.
359                ELSE
360                   to_be_resorted => ql_av
361                ENDIF
362             ENDIF
363
364          CASE ( 'ql_c' )
365             IF ( av == 0 )  THEN
366                to_be_resorted => ql_c
367             ELSE
368                to_be_resorted => ql_c_av
369             ENDIF
370
371          CASE ( 'ql_v' )
372             IF ( av == 0 )  THEN
373                to_be_resorted => ql_v
374             ELSE
375                to_be_resorted => ql_v_av
376             ENDIF
377
378          CASE ( 'ql_vp' )
379             IF ( av == 0 )  THEN
380                DO  i = nxl, nxr
381                   DO  j = nys, nyn
382                      DO  k = nzb, nz_do3d
383                         psi = prt_start_index(k,j,i)
384                         DO  n = psi, psi+prt_count(k,j,i)-1
385                            tend(k,j,i) = tend(k,j,i) + &
386                                          particles(n)%weight_factor / &
387                                          prt_count(k,j,i)
388                         ENDDO
389                      ENDDO
390                   ENDDO
391                ENDDO
392                CALL exchange_horiz( tend, nbgp )
393                DO  i = nxlg, nxrg
394                   DO  j = nysg, nyng
395                      DO  k = nzb, nz_do3d
396                         local_pf(i,j,k) = tend(k,j,i)
397                      ENDDO
398                   ENDDO
399                ENDDO
400                resorted = .TRUE.
401             ELSE
402                CALL exchange_horiz( ql_vp_av, nbgp )
403                to_be_resorted => ql_vp_av
404             ENDIF
405
406          CASE ( 'qr' )
407             IF ( av == 0 )  THEN
408                to_be_resorted => qr
409             ELSE
410                to_be_resorted => qr_av
411             ENDIF
412
413          CASE ( 'qv' )
414             IF ( av == 0 )  THEN
415                DO  i = nxlg, nxrg
416                   DO  j = nysg, nyng
417                      DO  k = nzb, nz_do3d
418                         local_pf(i,j,k) = q(k,j,i) - ql(k,j,i)
419                      ENDDO
420                   ENDDO
421                ENDDO
422                resorted = .TRUE.
423             ELSE
424                to_be_resorted => qv_av
425             ENDIF
426
427          CASE ( 'rho' )
428             IF ( av == 0 )  THEN
429                to_be_resorted => rho
430             ELSE
431                to_be_resorted => rho_av
432             ENDIF
433
434          CASE ( 's' )
435             IF ( av == 0 )  THEN
436                to_be_resorted => q
437             ELSE
438                to_be_resorted => s_av
439             ENDIF
440
441          CASE ( 'sa' )
442             IF ( av == 0 )  THEN
443                to_be_resorted => sa
444             ELSE
445                to_be_resorted => sa_av
446             ENDIF
447
448          CASE ( 'u' )
449             IF ( av == 0 )  THEN
450                to_be_resorted => u
451             ELSE
452                to_be_resorted => u_av
453             ENDIF
454
455          CASE ( 'v' )
456             IF ( av == 0 )  THEN
457                to_be_resorted => v
458             ELSE
459                to_be_resorted => v_av
460             ENDIF
461
462          CASE ( 'vpt' )
463             IF ( av == 0 )  THEN
464                to_be_resorted => vpt
465             ELSE
466                to_be_resorted => vpt_av
467             ENDIF
468
469          CASE ( 'w' )
470             IF ( av == 0 )  THEN
471                to_be_resorted => w
472             ELSE
473                to_be_resorted => w_av
474             ENDIF
475
476          CASE DEFAULT
477!
478!--          User defined quantity
479             CALL user_data_output_3d( av, do3d(av,if), found, local_pf, &
480                                       nz_do3d )
481             resorted = .TRUE.
482
483             IF ( .NOT. found )  THEN
484                message_string =  'no output available for: ' //   &
485                                  TRIM( do3d(av,if) )
486                CALL message( 'data_output_3d', 'PA0182', 0, 0, 0, 6, 0 )
487             ENDIF
488
489       END SELECT
490
491!
492!--    Resort the array to be output, if not done above
493       IF ( .NOT. resorted )  THEN
494          DO  i = nxlg, nxrg
495             DO  j = nysg, nyng
496                DO  k = nzb, nz_do3d
497                   local_pf(i,j,k) = to_be_resorted(k,j,i)
498                ENDDO
499             ENDDO
500          ENDDO
501       ENDIF
502
503!
504!--    Output of the volume data information for the AVS-FLD-file.
505       do3d_avs_n = do3d_avs_n + 1
506       IF ( myid == 0  .AND.  avs_output )  THEN
507!
508!--       AVS-labels must not contain any colons. Hence they must be removed
509!--       from the time character string.
510          simulated_time_mod = simulated_time_chr
511          DO  WHILE ( SCAN( simulated_time_mod, ':' ) /= 0 )
512             pos = SCAN( simulated_time_mod, ':' )
513             simulated_time_mod(pos:pos) = '/'
514          ENDDO
515
516          IF ( av == 0 )  THEN
517             WRITE ( 33, 3300 )  do3d_avs_n, TRIM( avs_data_file ), &
518                                 skip_do_avs, TRIM( do3d(av,if) ), &
519                                 TRIM( simulated_time_mod )
520          ELSE
521             WRITE ( 33, 3300 )  do3d_avs_n, TRIM( avs_data_file ), &
522                                 skip_do_avs, TRIM( do3d(av,if) ) // &
523                                 ' averaged', TRIM( simulated_time_mod )
524          ENDIF
525!
526!--       Determine the Skip-value for the next array. Record end and start
527!--       require 4 byte each.
528          skip_do_avs = skip_do_avs + ( ( ( nx+2*nbgp ) * ( ny+2*nbgp ) * &
529                                          ( nz_do3d+1 ) ) * 4 + 8 )
530       ENDIF
531
532!
533!--    Output of the 3D-array. (compressed/uncompressed)
534       IF ( do3d_compress )  THEN
535!
536!--       Compression, output of compression information on FLD-file and output
537!--       of compressed data.
538          CALL write_compressed( local_pf, 30, 33, myid, nxl, nxr, nyn, nys, &
539                                 nzb, nz_do3d, prec, nbgp )
540       ELSE
541!
542!--       Uncompressed output.
543#if defined( __parallel )
544          IF ( netcdf_output )  THEN
545             IF ( netcdf_data_format < 5 )  THEN
546!
547!--             Non-parallel netCDF output. Data is output in parallel in
548!--             FORTRAN binary format here, and later collected into one file by
549!--             combine_plot_fields
550                IF ( myid == 0 )  THEN
551                   WRITE ( 30 )  time_since_reference_point,                   &
552                                 do3d_time_count(av), av
553                ENDIF
554                DO  i = 0, io_blocks-1
555                   IF ( i == io_group )  THEN
556                      WRITE ( 30 )  nxlg, nxrg, nysg, nyng, nzb, nz_do3d
557                      WRITE ( 30 )  local_pf
558                   ENDIF
559#if defined( __parallel )
560                   CALL MPI_BARRIER( comm2d, ierr )
561#endif
562                ENDDO
563
564             ELSE
565#if defined( __netcdf )
566!
567!--             Parallel output in netCDF4/HDF5 format.
568!--             Do not output redundant ghost point data except for the
569!--             boundaries of the total domain.
570                IF ( nxr == nx  .AND.  nyn /= ny )  THEN
571                   nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_do3d(av,if), &
572                                  local_pf(nxl:nxrg,nys:nyn,nzb:nz_do3d),    &
573                      start = (/ nxl+1, nys+1, nzb+1, do3d_time_count(av) /), &
574                      count = (/ nxr-nxl+1+nbgp, nyn-nys+1, nz_do3d-nzb+1, 1 /) )
575                ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
576                   nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_do3d(av,if), &
577                                  local_pf(nxl:nxr,nys:nyng,nzb:nz_do3d),    &
578                      start = (/ nxl+1, nys+1, nzb+1, do3d_time_count(av) /), &
579                      count = (/ nxr-nxl+1, nyn-nys+1+nbgp, nz_do3d-nzb+1, 1 /) )
580                ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
581                   nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_do3d(av,if), &
582                                  local_pf(nxl:nxrg,nys:nyng,nzb:nz_do3d),  &
583                      start = (/ nxl+1, nys+1, nzb+1, do3d_time_count(av) /), &
584                      count = (/ nxr-nxl+1+nbgp, nyn-nys+1+nbgp, nz_do3d-nzb+1, 1 /) )
585                ELSE
586                   nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_do3d(av,if), &
587                                  local_pf(nxl:nxr,nys:nyn,nzb:nz_do3d),      &
588                      start = (/ nxl+1, nys+1, nzb+1, do3d_time_count(av) /), &
589                      count = (/ nxr-nxl+1, nyn-nys+1, nz_do3d-nzb+1, 1 /) )
590                ENDIF
591                CALL handle_netcdf_error( 'data_output_3d', 386 )
592#endif
593             ENDIF
594          ENDIF
595#else
596          IF ( avs_output )  THEN
597             WRITE ( 30 )  local_pf(nxl:nxr+1,nys:nyn+1,:)
598          ENDIF
599#if defined( __netcdf )
600          IF ( netcdf_output )  THEN
601
602             nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_do3d(av,if),    &
603                               local_pf(nxl:nxr+1,nys:nyn+1,nzb:nz_do3d),  &
604                               start = (/ 1, 1, 1, do3d_time_count(av) /), &
605                               count = (/ nx+2, ny+2, nz_do3d-nzb+1, 1 /) )
606             CALL handle_netcdf_error( 'data_output_3d', 446 )
607
608          ENDIF
609#endif
610#endif
611       ENDIF
612
613       if = if + 1
614
615    ENDDO
616
617!
618!-- Deallocate temporary array.
619    DEALLOCATE( local_pf )
620
621
622    CALL cpu_log (log_point(14),'data_output_3d','stop','nobarrier')
623
624!
625!-- Formats.
6263300 FORMAT ('variable ',I4,'  file=',A,'  filetype=unformatted  skip=',I12/ &
627             'label = ',A,A)
628
629 END SUBROUTINE data_output_3d
Note: See TracBrowser for help on using the repository browser.