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

Last change on this file since 1403 was 1360, checked in by hoffmann, 10 years ago

last commit documented

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