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

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

code has been put under the GNU General Public License (v3)

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