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

Last change on this file since 2000 was 2000, checked in by knoop, 5 years ago

Forced header and separation lines into 80 columns

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