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

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

optimization of two-moments cloud physics

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