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

Last change on this file since 1906 was 1832, checked in by hoffmann, 9 years ago

last commit documented

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