source: palm/trunk/SOURCE/data_output_ptseries.f90 @ 2101

Last change on this file since 2101 was 2101, checked in by suehring, 7 years ago

last commit documented

  • Property svn:keywords set to Id
File size: 16.9 KB
RevLine 
[1682]1!> @file data_output_ptseries.f90
[2000]2!------------------------------------------------------------------------------!
[1036]3! This file is part of PALM.
4!
[2000]5! PALM is free software: you can redistribute it and/or modify it under the
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! version.
[1036]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!
[2101]17! Copyright 1997-2017 Leibniz Universitaet Hannover
[2000]18!------------------------------------------------------------------------------!
[1036]19!
[263]20! Current revisions:
[1]21! -----------------
[2001]22!
23!
[1321]24! Former revisions:
25! -----------------
26! $Id: data_output_ptseries.f90 2101 2017-01-05 16:42:31Z suehring $
27!
[2001]28! 2000 2016-08-20 18:09:15Z knoop
29! Forced header and separation lines into 80 columns
30!
[1832]31! 1831 2016-04-07 13:15:51Z hoffmann
32! curvature_solution_effects moved to particle_attributes
33!
[1784]34! 1783 2016-03-06 18:36:17Z raasch
35! netcdf module name changed + related changes
36!
[1683]37! 1682 2015-10-07 23:56:08Z knoop
38! Code annotations made doxygen readable
39!
[1360]40! 1359 2014-04-11 17:15:14Z hoffmann
41! New particle structure integrated.
42!
[1354]43! 1353 2014-04-08 15:21:23Z heinze
44! REAL constants provided with KIND-attribute
45!
[1329]46! 1327 2014-03-21 11:00:16Z raasch
47! -netcdf output queries
48!
[1321]49! 1320 2014-03-20 08:40:49Z raasch
[1320]50! ONLY-attribute added to USE-statements,
51! kind-parameters added to all INTEGER and REAL declaration statements,
52! kinds are defined in new module kinds,
53! revision history before 2012 removed,
54! comment fields (!:) to be used for variable explanations added to
55! all variable declaration statements
[1]56!
[1319]57! 1318 2014-03-17 13:35:16Z raasch
58! barrier argument removed from cpu_log,
59! module interfaces removed
60!
[1037]61! 1036 2012-10-22 13:43:42Z raasch
62! code put under GPL (PALM 3.9)
63!
[826]64! 825 2012-02-19 03:03:44Z raasch
65! mean/minimum/maximum particle radius added as output quantity,
66! particle attributes speed_x|y|z_sgs renamed rvar1|2|3
67!
[1]68! Revision 1.1  2006/08/04 14:24:18  raasch
69! Initial revision
70!
71!
72! Description:
73! ------------
[1682]74!> Output of particle data timeseries in NetCDF format.
[1]75!------------------------------------------------------------------------------!
[1682]76 SUBROUTINE data_output_ptseries
77 
[1]78
[1320]79    USE control_parameters,                                                    &
[1327]80        ONLY:  dopts_time_count, time_since_reference_point
[1320]81
82    USE cpulog,                                                                &
83        ONLY:  cpu_log, log_point
84
85    USE indices,                                                               &
[1359]86        ONLY: nxl, nxr, nys, nyn, nzb, nzt
[1320]87
88    USE kinds
89
[1783]90#if defined( __netcdf )
91    USE NETCDF
92#endif
[1320]93
[1783]94    USE netcdf_interface,                                                      &
95        ONLY:  dopts_num, id_set_pts, id_var_dopts, id_var_time_pts, nc_stat,  &
96               netcdf_handle_error
97
[1320]98    USE particle_attributes,                                                   &
[1831]99        ONLY:  curvature_solution_effects, grid_particles, number_of_particles,&
100               number_of_particle_groups, particles, prt_count
[1320]101
[1]102    USE pegrid
103
104    IMPLICIT NONE
105
106
[1682]107    INTEGER(iwp) ::  i    !<
108    INTEGER(iwp) ::  inum !<
109    INTEGER(iwp) ::  j    !<
110    INTEGER(iwp) ::  jg   !<
111    INTEGER(iwp) ::  k    !<
112    INTEGER(iwp) ::  n    !<
[1]113
[1682]114    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  pts_value   !<
115    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  pts_value_l !<
[1]116
117
118    CALL cpu_log( log_point(36), 'data_output_ptseries', 'start' )
119
[1327]120    IF ( myid == 0 )  THEN
[1]121!
122!--    Open file for time series output in NetCDF format
123       dopts_time_count = dopts_time_count + 1
124       CALL check_open( 109 )
125#if defined( __netcdf )
126!
127!--    Update the particle time series time axis
[291]128       nc_stat = NF90_PUT_VAR( id_set_pts, id_var_time_pts,      &
129                               (/ time_since_reference_point /), &
[1]130                               start = (/ dopts_time_count /), count = (/ 1 /) )
[1783]131       CALL netcdf_handle_error( 'data_output_ptseries', 391 )
[1]132#endif
133
134    ENDIF
135
[825]136    ALLOCATE( pts_value(0:number_of_particle_groups,dopts_num), &
137              pts_value_l(0:number_of_particle_groups,dopts_num) )
138
[1353]139    pts_value_l = 0.0_wp
140    pts_value_l(:,16) = 9999999.9_wp    ! for calculation of minimum radius
[1]141
142!
143!-- Calculate or collect the particle time series quantities for all particles
144!-- and seperately for each particle group (if there is more than one group)
[1359]145    DO  i = nxl, nxr
146       DO  j = nys, nyn
147          DO  k = nzb, nzt
148             number_of_particles = prt_count(k,j,i)
149             IF (number_of_particles <= 0)  CYCLE
150             particles => grid_particles(k,j,i)%particles(1:number_of_particles)
151             DO  n = 1, number_of_particles
[1]152
[1359]153                IF ( particles(n)%particle_mask )  THEN  ! Restrict analysis to active particles
[1]154
[1359]155                   pts_value_l(0,1)  = pts_value_l(0,1) + 1.0_wp  ! total # of particles
156                   pts_value_l(0,2)  = pts_value_l(0,2) +                      &
157                          ( particles(n)%x - particles(n)%origin_x )  ! mean x
158                   pts_value_l(0,3)  = pts_value_l(0,3) +                      &
159                          ( particles(n)%y - particles(n)%origin_y )  ! mean y
160                   pts_value_l(0,4)  = pts_value_l(0,4) +                      &
161                          ( particles(n)%z - particles(n)%origin_z )  ! mean z
162                   pts_value_l(0,5)  = pts_value_l(0,5) + particles(n)%z        ! mean z (absolute)
163                   pts_value_l(0,6)  = pts_value_l(0,6) + particles(n)%speed_x  ! mean u
164                   pts_value_l(0,7)  = pts_value_l(0,7) + particles(n)%speed_y  ! mean v
165                   pts_value_l(0,8)  = pts_value_l(0,8) + particles(n)%speed_z  ! mean w
166                   IF ( .NOT. curvature_solution_effects )  THEN
167                      pts_value_l(0,9)  = pts_value_l(0,9)  + particles(n)%rvar1 ! mean sgsu
168                      pts_value_l(0,10) = pts_value_l(0,10) + particles(n)%rvar2 ! mean sgsv
169                      pts_value_l(0,11) = pts_value_l(0,11) + particles(n)%rvar3 ! mean sgsw
170                   ENDIF
171                   IF ( particles(n)%speed_z > 0.0_wp )  THEN
172                      pts_value_l(0,12) = pts_value_l(0,12) + 1.0_wp  ! # of upward moving prts
173                      pts_value_l(0,13) = pts_value_l(0,13) +                  &
174                                              particles(n)%speed_z ! mean w upw.
175                   ELSE
176                      pts_value_l(0,14) = pts_value_l(0,14) +                  &
177                                              particles(n)%speed_z ! mean w down
178                   ENDIF
179                   pts_value_l(0,15) = pts_value_l(0,15) + particles(n)%radius ! mean rad
180                   pts_value_l(0,16) = MIN( pts_value_l(0,16), particles(n)%radius ) ! minrad
181                   pts_value_l(0,17) = MAX( pts_value_l(0,17), particles(n)%radius ) ! maxrad
182                   pts_value_l(0,18) = pts_value_l(0,18) + 1.0_wp
183                   pts_value_l(0,19) = pts_value_l(0,18) + 1.0_wp
[1]184!
[1359]185!--                Repeat the same for the respective particle group
186                   IF ( number_of_particle_groups > 1 )  THEN
187                      jg = particles(n)%group
[1]188
[1359]189                      pts_value_l(jg,1)  = pts_value_l(jg,1) + 1.0_wp
190                      pts_value_l(jg,2)  = pts_value_l(jg,2) +                   &
191                           ( particles(n)%x - particles(n)%origin_x )
192                      pts_value_l(jg,3)  = pts_value_l(jg,3) +                   &
193                           ( particles(n)%y - particles(n)%origin_y )
194                      pts_value_l(jg,4)  = pts_value_l(jg,4) +                   &
195                           ( particles(n)%z - particles(n)%origin_z )
196                      pts_value_l(jg,5)  = pts_value_l(jg,5) + particles(n)%z
197                      pts_value_l(jg,6)  = pts_value_l(jg,6) + particles(n)%speed_x
198                      pts_value_l(jg,7)  = pts_value_l(jg,7) + particles(n)%speed_y
199                      pts_value_l(jg,8)  = pts_value_l(jg,8) + particles(n)%speed_z
200                      IF ( .NOT. curvature_solution_effects )  THEN
201                         pts_value_l(jg,9)  = pts_value_l(jg,9)  + particles(n)%rvar1
202                         pts_value_l(jg,10) = pts_value_l(jg,10) + particles(n)%rvar2
203                         pts_value_l(jg,11) = pts_value_l(jg,11) + particles(n)%rvar3
204                      ENDIF
205                      IF ( particles(n)%speed_z > 0.0_wp )  THEN
206                         pts_value_l(jg,12) = pts_value_l(jg,12) + 1.0_wp
207                         pts_value_l(jg,13) = pts_value_l(jg,13) + particles(n)%speed_z
208                      ELSE
209                         pts_value_l(jg,14) = pts_value_l(jg,14) + particles(n)%speed_z
210                      ENDIF
211                      pts_value_l(jg,15) = pts_value_l(jg,15) + particles(n)%radius
212                      pts_value_l(jg,16) = MIN( pts_value(jg,16), particles(n)%radius )
213                      pts_value_l(jg,17) = MAX( pts_value(jg,17), particles(n)%radius )
214                      pts_value_l(jg,18) = pts_value_l(jg,18) + 1.0_wp
215                      pts_value_l(jg,19) = pts_value_l(jg,19) + 1.0_wp
216                   ENDIF
[1]217
[1359]218                ENDIF
[1]219
[1359]220             ENDDO
221
222          ENDDO
223       ENDDO
[1]224    ENDDO
225
[1359]226
[1]227#if defined( __parallel )
228!
229!-- Sum values of the subdomains
230    inum = number_of_particle_groups + 1
231
[622]232    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[824]233    CALL MPI_ALLREDUCE( pts_value_l(0,1), pts_value(0,1), 15*inum, MPI_REAL, &
[1]234                        MPI_SUM, comm2d, ierr )
[622]235    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[824]236    CALL MPI_ALLREDUCE( pts_value_l(0,16), pts_value(0,16), inum, MPI_REAL, &
[825]237                        MPI_MIN, comm2d, ierr )
238    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
239    CALL MPI_ALLREDUCE( pts_value_l(0,17), pts_value(0,17), inum, MPI_REAL, &
[1]240                        MPI_MAX, comm2d, ierr )
[622]241    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[825]242    CALL MPI_ALLREDUCE( pts_value_l(0,18), pts_value(0,18), inum, MPI_REAL, &
243                        MPI_MAX, comm2d, ierr )
244    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
245    CALL MPI_ALLREDUCE( pts_value_l(0,19), pts_value(0,19), inum, MPI_REAL, &
[1]246                        MPI_MIN, comm2d, ierr )
247#else
[825]248    pts_value(:,1:19) = pts_value_l(:,1:19)
[1]249#endif
250
251!
[825]252!-- Normalize the above calculated quantities (except min/max values) with the
253!-- total number of particles
[1]254    IF ( number_of_particle_groups > 1 )  THEN
255       inum = number_of_particle_groups
256    ELSE
257       inum = 0
258    ENDIF
259
260    DO  j = 0, inum
261
[1353]262       IF ( pts_value(j,1) > 0.0_wp )  THEN
[1]263
[824]264          pts_value(j,2:15) = pts_value(j,2:15) / pts_value(j,1)
[1353]265          IF ( pts_value(j,12) > 0.0_wp  .AND.  pts_value(j,12) < 1.0_wp )  THEN
[1]266             pts_value(j,13) = pts_value(j,13) / pts_value(j,12)
[1353]267             pts_value(j,14) = pts_value(j,14) / ( 1.0_wp - pts_value(j,12) )
268          ELSEIF ( pts_value(j,12) == 0.0_wp )  THEN
269             pts_value(j,13) = -1.0_wp
[1]270          ELSE
[1353]271             pts_value(j,14) = -1.0_wp
[1]272          ENDIF
273
274       ENDIF
275
276    ENDDO
277
278!
279!-- Calculate higher order moments of particle time series quantities,
280!-- seperately for each particle group (if there is more than one group)
[1359]281    DO  i = nxl, nxr
282       DO  j = nys, nyn
283          DO  k = nzb, nzt
284             number_of_particles = prt_count(k,j,i)
285             IF (number_of_particles <= 0)  CYCLE
286             particles => grid_particles(k,j,i)%particles(1:number_of_particles)
287             DO  n = 1, number_of_particles
[1]288
[1359]289                pts_value_l(0,20) = pts_value_l(0,20) + ( particles(n)%x - &
290                                    particles(n)%origin_x - pts_value(0,2) )**2 ! x*2
291                pts_value_l(0,21) = pts_value_l(0,21) + ( particles(n)%y - &
292                                    particles(n)%origin_y - pts_value(0,3) )**2 ! y*2
293                pts_value_l(0,22) = pts_value_l(0,22) + ( particles(n)%z - &
294                                    particles(n)%origin_z - pts_value(0,4) )**2 ! z*2
295                pts_value_l(0,23) = pts_value_l(0,23) + ( particles(n)%speed_x - &
296                                                         pts_value(0,6) )**2   ! u*2
297                pts_value_l(0,24) = pts_value_l(0,24) + ( particles(n)%speed_y - &
298                                                          pts_value(0,7) )**2   ! v*2
299                pts_value_l(0,25) = pts_value_l(0,25) + ( particles(n)%speed_z - &
300                                                          pts_value(0,8) )**2   ! w*2
301                IF ( .NOT. curvature_solution_effects )  THEN
302                   pts_value_l(0,26) = pts_value_l(0,26) + ( particles(n)%rvar1 - &
303                                                             pts_value(0,9) )**2   ! u"2
304                   pts_value_l(0,27) = pts_value_l(0,27) + ( particles(n)%rvar2 - &
305                                                             pts_value(0,10) )**2  ! v"2
306                   pts_value_l(0,28) = pts_value_l(0,28) + ( particles(n)%rvar3 - &
307                                                             pts_value(0,11) )**2  ! w"2
308                ENDIF
[1]309!
[1359]310!--             Repeat the same for the respective particle group
311                IF ( number_of_particle_groups > 1 )  THEN
312                   jg = particles(n)%group
[1]313
[1359]314                   pts_value_l(jg,20) = pts_value_l(jg,20) + ( particles(n)%x - &
315                                       particles(n)%origin_x - pts_value(jg,2) )**2
316                   pts_value_l(jg,21) = pts_value_l(jg,21) + ( particles(n)%y - &
317                                       particles(n)%origin_y - pts_value(jg,3) )**2
318                   pts_value_l(jg,22) = pts_value_l(jg,22) + ( particles(n)%z - &
319                                       particles(n)%origin_z - pts_value(jg,4) )**2
320                   pts_value_l(jg,23) = pts_value_l(jg,23) + ( particles(n)%speed_x - &
321                                                             pts_value(jg,6) )**2
322                   pts_value_l(jg,24) = pts_value_l(jg,24) + ( particles(n)%speed_y - &
323                                                             pts_value(jg,7) )**2
324                   pts_value_l(jg,25) = pts_value_l(jg,25) + ( particles(n)%speed_z - &
325                                                             pts_value(jg,8) )**2
326                   IF ( .NOT. curvature_solution_effects )  THEN
327                      pts_value_l(jg,26) = pts_value_l(jg,26) + ( particles(n)%rvar1 - &
328                                                                pts_value(jg,9) )**2
329                      pts_value_l(jg,27) = pts_value_l(jg,27) + ( particles(n)%rvar2 - &
330                                                                pts_value(jg,10) )**2
331                      pts_value_l(jg,28) = pts_value_l(jg,28) + ( particles(n)%rvar3 - &
332                                                                pts_value(jg,11) )**2
333                   ENDIF
334                ENDIF
[1]335
[1359]336             ENDDO
337          ENDDO
338       ENDDO
[1]339    ENDDO
340
[825]341    pts_value_l(0,29) = ( number_of_particles - pts_value(0,1) / numprocs )**2
[1]342                                                 ! variance of particle numbers
343    IF ( number_of_particle_groups > 1 )  THEN
344       DO  j = 1, number_of_particle_groups
[825]345          pts_value_l(j,29) = ( pts_value_l(j,1) - &
[1]346                                pts_value(j,1) / numprocs )**2
347       ENDDO
348    ENDIF
349
350#if defined( __parallel )
351!
352!-- Sum values of the subdomains
353    inum = number_of_particle_groups + 1
354
[622]355    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[825]356    CALL MPI_ALLREDUCE( pts_value_l(0,20), pts_value(0,20), inum*10, MPI_REAL, &
[1]357                        MPI_SUM, comm2d, ierr )
358#else
[825]359    pts_value(:,20:29) = pts_value_l(:,20:29)
[1]360#endif
361
362!
363!-- Normalize the above calculated quantities with the total number of
364!-- particles
365    IF ( number_of_particle_groups > 1 )  THEN
366       inum = number_of_particle_groups
367    ELSE
368       inum = 0
369    ENDIF
370
371    DO  j = 0, inum
372
[1353]373       IF ( pts_value(j,1) > 0.0_wp )  THEN
[825]374          pts_value(j,20:28) = pts_value(j,20:28) / pts_value(j,1)
[1]375       ENDIF
[825]376       pts_value(j,29) = pts_value(j,29) / numprocs
[1]377
378    ENDDO
379
380#if defined( __netcdf )
381!
382!-- Output particle time series quantities in NetCDF format
[1327]383    IF ( myid == 0 )  THEN
[1]384       DO  j = 0, inum
385          DO  i = 1, dopts_num
386             nc_stat = NF90_PUT_VAR( id_set_pts, id_var_dopts(i,j),  &
387                                     (/ pts_value(j,i) /),           &
388                                     start = (/ dopts_time_count /), &
389                                     count = (/ 1 /) )
[1783]390             CALL netcdf_handle_error( 'data_output_ptseries', 392 )
[1]391          ENDDO
392       ENDDO
393    ENDIF
394#endif
395
[825]396    DEALLOCATE( pts_value, pts_value_l )
397
[1318]398    CALL cpu_log( log_point(36), 'data_output_ptseries', 'stop' )
[1]399
400 END SUBROUTINE data_output_ptseries
Note: See TracBrowser for help on using the repository browser.