source: flexpart.git/src/timemanager.f90 @ 1a08571

10.4.1_peseiFPv9.3.1FPv9.3.1b_testingFPv9.3.2GFS_025bugfixes+enhancementsdevfp9.3.1-20161214-nc4grib2nc4_repairrelease-10release-10.4.1scaling-bugunivie
Last change on this file since 1a08571 was 1a08571, checked in by Ignacio Pisso <Ignacio.Pisso@…>, 9 years ago

fix unitialised time variable in timemanager that would give random times at simulation start

  • Property mode set to 100644
File size: 23.3 KB
Line 
1!**********************************************************************
2! Copyright 1998,1999,2000,2001,2002,2005,2007,2008,2009,2010         *
3! Andreas Stohl, Petra Seibert, A. Frank, Gerhard Wotawa,             *
4! Caroline Forster, Sabine Eckhardt, John Burkhart, Harald Sodemann   *
5!                                                                     *
6! This file is part of FLEXPART.                                      *
7!                                                                     *
8! FLEXPART is free software: you can redistribute it and/or modify    *
9! it under the terms of the GNU General Public License as published by*
10! the Free Software Foundation, either version 3 of the License, or   *
11! (at your option) any later version.                                 *
12!                                                                     *
13! FLEXPART is distributed in the hope that it will be useful,         *
14! but WITHOUT ANY WARRANTY; without even the implied warranty of      *
15! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
16! GNU General Public License for more details.                        *
17!                                                                     *
18! You should have received a copy of the GNU General Public License   *
19! along with FLEXPART.  If not, see <http://www.gnu.org/licenses/>.   *
20!**********************************************************************
21
22subroutine timemanager
23
24  !*****************************************************************************
25  !                                                                            *
26  ! Handles the computation of trajectories, i.e. determines which             *
27  ! trajectories have to be computed at what time.                             *
28  ! Manages dry+wet deposition routines, radioactive decay and the computation *
29  ! of concentrations.                                                         *
30  !                                                                            *
31  !     Author: A. Stohl                                                       *
32  !                                                                            *
33  !     20 May 1996                                                            *
34  !                                                                            *
35  !*****************************************************************************
36  !  Changes, Bernd C. Krueger, Feb. 2001:                                     *
37  !        Call of convmix when new windfield is read                          *
38  !------------------------------------                                        *
39  !  Changes Petra Seibert, Sept 2002                                          *
40  !     fix wet scavenging problem                                             *
41  !     Code may not be correct for decay of deposition!                       *
42  !  Changes Petra Seibert, Nov 2002                                           *
43  !     call convection BEFORE new fields are read in BWD mode                 *
44  !  Changes Caroline Forster, Feb 2005                                        *
45  !new interface between flexpart and convection scheme                        *
46  !Emanuel's latest subroutine convect43c.f is used                            *
47  !*****************************************************************************
48  !                                                                            *
49  ! Variables:                                                                 *
50  ! DEP                .true. if either wet or dry deposition is switched on   *
51  ! decay(maxspec) [1/s] decay constant for radioactive decay                  *
52  ! DRYDEP             .true. if dry deposition is switched on                 *
53  ! ideltas [s]        modelling period                                        *
54  ! itime [s]          actual temporal position of calculation                 *
55  ! ldeltat [s]        time since computation of radioact. decay of depositions*
56  ! loutaver [s]       averaging period for concentration calculations         *
57  ! loutend [s]        end of averaging for concentration calculations         *
58  ! loutnext [s]       next time at which output fields shall be centered      *
59  ! loutsample [s]     sampling interval for averaging of concentrations       *
60  ! loutstart [s]      start of averaging for concentration calculations       *
61  ! loutstep [s]       time interval for which concentrations shall be         *
62  !                    calculated                                              *
63  ! npoint(maxpart)    index, which starting point the trajectory has          *
64  !                    starting positions of trajectories                      *
65  ! nstop              serves as indicator for fate of particles               *
66  !                    in the particle loop                                    *
67  ! nstop1             serves as indicator for wind fields (see getfields)     *
68  ! outnum             number of samples for each concentration calculation    *
69  ! outnum             number of samples for each concentration calculation    *
70  ! prob               probability of absorption at ground due to dry          *
71  !                    deposition                                              *
72  ! WETDEP             .true. if wet deposition is switched on                 *
73  ! weight             weight for each concentration sample (1/2 or 1)         *
74  ! uap(maxpart),ucp(maxpart),uzp(maxpart) = random velocities due to          *
75  !                    turbulence                                              *
76  ! us(maxpart),vs(maxpart),ws(maxpart) = random velocities due to inter-      *
77  !                    polation                                                *
78  ! xtra1(maxpart), ytra1(maxpart), ztra1(maxpart) =                           *
79  !                    spatial positions of trajectories                       *
80  !                                                                            *
81  ! Constants:                                                                 *
82  ! maxpart            maximum number of trajectories                          *
83  !                                                                            *
84  !*****************************************************************************
85
86  use unc_mod
87  use point_mod
88  use xmass_mod
89  use flux_mod
90  use outg_mod
91  use oh_mod
92  use par_mod
93  use com_mod
94
95  implicit none
96
97  integer :: j,ks,kp,l,n,itime,nstop,nstop1
98! integer :: ksp
99  integer :: loutnext,loutstart,loutend
100  integer :: ix,jy,ldeltat,itage,nage
101  real :: outnum,weight,prob(maxspec)
102  real :: uap(maxpart),ucp(maxpart),uzp(maxpart),decfact
103  real :: us(maxpart),vs(maxpart),ws(maxpart)
104  integer(kind=2) :: cbt(maxpart)
105  real :: drydeposit(maxspec),gridtotalunc,wetgridtotalunc
106  real :: drygridtotalunc,xold,yold,zold,xmassfract
107  !double precision xm(maxspec,maxpointspec_act),
108  !    +                 xm_depw(maxspec,maxpointspec_act),
109  !    +                 xm_depd(maxspec,maxpointspec_act)
110
111
112  !open(88,file='TEST.dat')
113
114  ! First output for time 0
115  !************************
116
117  loutnext=loutstep/2
118  outnum=0.
119  loutstart=loutnext-loutaver/2
120  loutend=loutnext+loutaver/2
121
122  !  open(127,file=path(2)(1:length(2))//'depostat.dat'
123  !    +  ,form='unformatted')
124  !write (*,*) 'writing deposition statistics depostat.dat!'
125
126  !**********************************************************************
127  ! Loop over the whole modelling period in time steps of mintime seconds
128  !**********************************************************************
129
130
131  !write(*,45) itime,numpart,gridtotalunc,wetgridtotalunc,drygridtotalunc
132  itime=0 ! initialise to avoid random numbers on output IP 2015-03-02
133  write(*,46) float(itime)/3600,itime,numpart
134  if (verbosity.gt.0) then
135    write (*,*) 'timemanager> starting simulation'
136    if (verbosity.gt.1) then
137      CALL SYSTEM_CLOCK(count_clock)
138      WRITE(*,*) 'timemanager> SYSTEM CLOCK',(count_clock - count_clock0)/real(count_rate)
139    endif     
140  endif
141
142  do itime=0,ideltas,lsynctime
143    if (verbosity.gt.0) then
144           write (*,*) 'timemanager>  itime=', itime
145    endif
146
147
148  ! Computation of wet deposition, OH reaction and mass transfer
149  ! between two species every lsynctime seconds
150  ! maybe wet depo frequency can be relaxed later but better be on safe side
151  ! wetdepo must be called BEFORE new fields are read in but should not
152  ! be called in the very beginning before any fields are loaded, or
153  ! before particles are in the system
154  ! Code may not be correct for decay of deposition
155  ! changed by Petra Seibert 9/02
156  !********************************************************************
157
158    if (WETDEP .and. itime .ne. 0 .and. numpart .gt. 0) then
159        if (verbosity.gt.0) then
160           write (*,*) 'timemanager> call wetdepo'
161        endif     
162         call wetdepo(itime,lsynctime,loutnext)
163    endif
164
165    if (OHREA .and. itime .ne. 0 .and. numpart .gt. 0) &
166         call ohreaction(itime,lsynctime,loutnext)
167
168    if (ASSSPEC .and. itime .ne. 0 .and. numpart .gt. 0) then
169       stop 'associated species not yet implemented!'
170  !     call transferspec(itime,lsynctime,loutnext)
171    endif
172
173  ! compute convection for backward runs
174  !*************************************
175
176   if ((ldirect.eq.-1).and.(lconvection.eq.1).and.(itime.lt.0)) then
177        if (verbosity.gt.0) then
178           write (*,*) 'timemanager> call convmix -- backward'
179        endif         
180      call convmix(itime)
181        if (verbosity.gt.1) then
182          !CALL SYSTEM_CLOCK(count_clock, count_rate, count_max)
183          CALL SYSTEM_CLOCK(count_clock)
184          WRITE(*,*) 'timemanager> SYSTEM CLOCK',(count_clock - count_clock0)/real(count_rate)
185        endif
186   endif
187
188  ! Get necessary wind fields if not available
189  !*******************************************
190    if (verbosity.gt.0) then
191           write (*,*) 'timemanager> call getfields'
192    endif
193    call getfields(itime,nstop1)
194        if (verbosity.gt.1) then
195          CALL SYSTEM_CLOCK(count_clock)
196          WRITE(*,*) 'timemanager> SYSTEM CLOCK',(count_clock - count_clock0)/real(count_rate)
197        endif
198    if (nstop1.gt.1) stop 'NO METEO FIELDS AVAILABLE'
199
200  ! Release particles
201  !******************
202
203    !if (verbosity.gt.0) then
204    !       write (*,*) 'timemanager>  Release particles'
205    !endif
206
207    if (mdomainfill.ge.1) then
208      if (itime.eq.0) then
209        if (verbosity.gt.0) then
210          write (*,*) 'timemanager>  call init_domainfill'
211        endif       
212        call init_domainfill
213      else
214        if (verbosity.gt.0) then
215          write (*,*) 'timemanager>  call boundcond_domainfill'
216        endif   
217        call boundcond_domainfill(itime,loutend)
218      endif
219    else
220      if (verbosity.gt.0) then
221        print*,'timemanager> call releaseparticles' 
222      endif
223      call releaseparticles(itime)
224      if (verbosity.gt.1) then
225        CALL SYSTEM_CLOCK(count_clock)
226        WRITE(*,*) 'timemanager> SYSTEM CLOCK',(count_clock - count_clock0)/real(count_rate)
227      endif
228    endif
229
230
231  ! Compute convective mixing for forward runs
232  ! for backward runs it is done before next windfield is read in
233  !**************************************************************
234
235   if ((ldirect.eq.1).and.(lconvection.eq.1)) then
236     if (verbosity.gt.0) then
237       write (*,*) 'timemanager> call convmix -- forward'
238     endif   
239     call convmix(itime)
240   endif
241
242  ! If middle of averaging period of output fields is reached, accumulated
243  ! deposited mass radioactively decays
244  !***********************************************************************
245
246    if (DEP.and.(itime.eq.loutnext).and.(ldirect.gt.0)) then
247      do ks=1,nspec
248      do kp=1,maxpointspec_act
249        if (decay(ks).gt.0.) then
250          do nage=1,nageclass
251            do l=1,nclassunc
252  ! Mother output grid
253              do jy=0,numygrid-1
254                do ix=0,numxgrid-1
255                  wetgridunc(ix,jy,ks,kp,l,nage)= &
256                       wetgridunc(ix,jy,ks,kp,l,nage)* &
257                       exp(-1.*outstep*decay(ks))
258                  drygridunc(ix,jy,ks,kp,l,nage)= &
259                       drygridunc(ix,jy,ks,kp,l,nage)* &
260                       exp(-1.*outstep*decay(ks))
261                end do
262              end do
263  ! Nested output grid
264              if (nested_output.eq.1) then
265                do jy=0,numygridn-1
266                  do ix=0,numxgridn-1
267                    wetgriduncn(ix,jy,ks,kp,l,nage)= &
268                         wetgriduncn(ix,jy,ks,kp,l,nage)* &
269                         exp(-1.*outstep*decay(ks))
270                    drygriduncn(ix,jy,ks,kp,l,nage)= &
271                         drygriduncn(ix,jy,ks,kp,l,nage)* &
272                         exp(-1.*outstep*decay(ks))
273                  end do
274                end do
275              endif
276            end do
277          end do
278        endif
279      end do
280      end do
281    endif
282
283  !!! CHANGE: These lines may be switched on to check the conservation
284  !!! of mass within FLEXPART
285  !   if (itime.eq.loutnext) then
286  !   do 247 ksp=1, nspec
287  !   do 247 kp=1, maxpointspec_act
288  !47         xm(ksp,kp)=0.
289
290  !   do 249 ksp=1, nspec
291  !     do 249 j=1,numpart
292  !          if (ioutputforeachrelease.eq.1) then
293  !            kp=npoint(j)
294  !          else
295  !            kp=1
296  !          endif
297  !       if (itra1(j).eq.itime) then
298  !          xm(ksp,kp)=xm(ksp,kp)+xmass1(j,ksp)
299  !         write(*,*) 'xmass: ',xmass1(j,ksp),j,ksp,nspec
300  !       endif
301  !49     continue
302  !  do 248 ksp=1,nspec
303  !  do 248 kp=1,maxpointspec_act
304  !  xm_depw(ksp,kp)=0.
305  !  xm_depd(ksp,kp)=0.
306  !     do 248 nage=1,nageclass
307  !       do 248 ix=0,numxgrid-1
308  !         do 248 jy=0,numygrid-1
309  !           do 248 l=1,nclassunc
310  !              xm_depw(ksp,kp)=xm_depw(ksp,kp)
311  !    +                  +wetgridunc(ix,jy,ksp,kp,l,nage)
312  !48                 xm_depd(ksp,kp)=xm_depd(ksp,kp)
313  !    +                  +drygridunc(ix,jy,ksp,kp,l,nage)
314  !             do 246 ksp=1,nspec
315  !46                    write(88,'(2i10,3e12.3)')
316  !    +              itime,ksp,(xm(ksp,kp),kp=1,maxpointspec_act),
317  !    +                (xm_depw(ksp,kp),kp=1,maxpointspec_act),
318  !    +                (xm_depd(ksp,kp),kp=1,maxpointspec_act)
319  !  endif
320  !!! CHANGE
321
322
323
324  ! Check whether concentrations are to be calculated
325  !**************************************************
326
327    if ((ldirect*itime.ge.ldirect*loutstart).and. &
328         (ldirect*itime.le.ldirect*loutend)) then ! add to grid
329      if (mod(itime-loutstart,loutsample).eq.0) then
330
331  ! If we are exactly at the start or end of the concentration averaging interval,
332  ! give only half the weight to this sample
333  !*****************************************************************************
334
335        if ((itime.eq.loutstart).or.(itime.eq.loutend)) then
336          weight=0.5
337        else
338          weight=1.0
339        endif
340        outnum=outnum+weight
341        call conccalc(itime,weight)
342      endif
343
344
345      if ((mquasilag.eq.1).and.(itime.eq.(loutstart+loutend)/2)) &
346           call partoutput_short(itime)    ! dump particle positions in extremely compressed format
347
348
349  ! Output and reinitialization of grid
350  ! If necessary, first sample of new grid is also taken
351  !*****************************************************
352
353      if ((itime.eq.loutend).and.(outnum.gt.0.)) then
354        if ((iout.le.3.).or.(iout.eq.5)) then
355          if (surf_only.ne.1) then
356          call concoutput(itime,outnum,gridtotalunc, &
357               wetgridtotalunc,drygridtotalunc)
358          else 
359  if (verbosity.eq.1) then
360     print*,'call concoutput_surf '
361     CALL SYSTEM_CLOCK(count_clock)
362     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
363  endif
364          call concoutput_surf(itime,outnum,gridtotalunc, &
365               wetgridtotalunc,drygridtotalunc)
366  if (verbosity.eq.1) then
367     print*,'called concoutput_surf '
368     CALL SYSTEM_CLOCK(count_clock)
369     WRITE(*,*) 'SYSTEM_CLOCK',count_clock - count_clock0   
370  endif
371          endif
372
373          if ((nested_output.eq.1).and.(surf_only.ne.1)) call concoutput_nest(itime,outnum)
374          if ((nested_output.eq.1).and.(surf_only.eq.1)) call concoutput_surf_nest(itime,outnum)
375          outnum=0.
376        endif
377        if ((iout.eq.4).or.(iout.eq.5)) call plumetraj(itime)
378        if (iflux.eq.1) call fluxoutput(itime)
379        !write(*,45) itime,numpart,gridtotalunc,wetgridtotalunc,drygridtotalunc
380        write(*,46) float(itime)/3600,itime,numpart
38145      format(i9,' SECONDS SIMULATED: ',i8, ' PARTICLES:    Uncertainty: ',3f7.3)
38246      format(' Simulated ',f7.1,' hours (',i9,' s), ',i8, ' particles')
383        if (ipout.ge.1) call partoutput(itime)    ! dump particle positions
384        loutnext=loutnext+loutstep
385        loutstart=loutnext-loutaver/2
386        loutend=loutnext+loutaver/2
387        if (itime.eq.loutstart) then
388          weight=0.5
389          outnum=outnum+weight
390          call conccalc(itime,weight)
391        endif
392
393
394  ! Check, whether particles are to be split:
395  ! If so, create new particles and attribute all information from the old
396  ! particles also to the new ones; old and new particles both get half the
397  ! mass of the old ones
398  !************************************************************************
399
400        if (ldirect*itime.ge.ldirect*itsplit) then
401          n=numpart
402          do j=1,numpart
403            if (ldirect*itime.ge.ldirect*itrasplit(j)) then
404              if (n.lt.maxpart) then
405                n=n+1
406                itrasplit(j)=2*(itrasplit(j)-itramem(j))+itramem(j)
407                itrasplit(n)=itrasplit(j)
408                itramem(n)=itramem(j)
409                itra1(n)=itra1(j)
410                idt(n)=idt(j)
411                npoint(n)=npoint(j)
412                nclass(n)=nclass(j)
413                xtra1(n)=xtra1(j)
414                ytra1(n)=ytra1(j)
415                ztra1(n)=ztra1(j)
416                uap(n)=uap(j)
417                ucp(n)=ucp(j)
418                uzp(n)=uzp(j)
419                us(n)=us(j)
420                vs(n)=vs(j)
421                ws(n)=ws(j)
422                cbt(n)=cbt(j)
423                do ks=1,nspec
424                  xmass1(j,ks)=xmass1(j,ks)/2.
425                  xmass1(n,ks)=xmass1(j,ks)
426                end do
427              endif
428            endif
429          end do
430          numpart=n
431        endif
432      endif
433    endif
434
435
436    if (itime.eq.ideltas) exit         ! almost finished
437
438  ! Compute interval since radioactive decay of deposited mass was computed
439  !************************************************************************
440
441    if (itime.lt.loutnext) then
442      ldeltat=itime-(loutnext-loutstep)
443    else                                  ! first half of next interval
444      ldeltat=itime-loutnext
445    endif
446
447
448  ! Loop over all particles
449  !************************
450
451    do j=1,numpart
452
453
454  ! If integration step is due, do it
455  !**********************************
456
457      if (itra1(j).eq.itime) then
458
459        if (ioutputforeachrelease.eq.1) then
460            kp=npoint(j)
461        else
462            kp=1
463        endif
464  ! Determine age class of the particle
465        itage=abs(itra1(j)-itramem(j))
466        do nage=1,nageclass
467          if (itage.lt.lage(nage)) exit
468        end do
469
470  ! Initialize newly released particle
471  !***********************************
472
473        if ((itramem(j).eq.itime).or.(itime.eq.0)) &
474             call initialize(itime,idt(j),uap(j),ucp(j),uzp(j), &
475             us(j),vs(j),ws(j),xtra1(j),ytra1(j),ztra1(j),cbt(j))
476
477  ! Memorize particle positions
478  !****************************
479
480        xold=xtra1(j)
481        yold=ytra1(j)
482        zold=ztra1(j)
483
484  ! Integrate Lagevin equation for lsynctime seconds
485  !*************************************************
486
487        call advance(itime,npoint(j),idt(j),uap(j),ucp(j),uzp(j), &
488             us(j),vs(j),ws(j),nstop,xtra1(j),ytra1(j),ztra1(j),prob, &
489             cbt(j))
490
491  ! Calculate the gross fluxes across layer interfaces
492  !***************************************************
493
494        if (iflux.eq.1) call calcfluxes(nage,j,xold,yold,zold)
495
496
497  ! Determine, when next time step is due
498  ! If trajectory is terminated, mark it
499  !**************************************
500
501        if (nstop.gt.1) then
502          if (linit_cond.ge.1) call initial_cond_calc(itime,j)
503          itra1(j)=-999999999
504        else
505          itra1(j)=itime+lsynctime
506
507
508  ! Dry deposition and radioactive decay for each species
509  ! Also check maximum (of all species) of initial mass remaining on the particle;
510  ! if it is below a threshold value, terminate particle
511  !*****************************************************************************
512
513          xmassfract=0.
514          do ks=1,nspec
515            if (decay(ks).gt.0.) then             ! radioactive decay
516              decfact=exp(-real(abs(lsynctime))*decay(ks))
517            else
518              decfact=1.
519            endif
520
521            if (DRYDEPSPEC(ks)) then        ! dry deposition
522              drydeposit(ks)=xmass1(j,ks)*prob(ks)*decfact
523              xmass1(j,ks)=xmass1(j,ks)*(1.-prob(ks))*decfact
524              if (decay(ks).gt.0.) then   ! correct for decay (see wetdepo)
525                drydeposit(ks)=drydeposit(ks)* &
526                     exp(real(abs(ldeltat))*decay(ks))
527              endif
528            else                           ! no dry deposition
529              xmass1(j,ks)=xmass1(j,ks)*decfact
530            endif
531
532
533            if (mdomainfill.eq.0) then
534              if (xmass(npoint(j),ks).gt.0.) &
535                   xmassfract=max(xmassfract,real(npart(npoint(j)))* &
536                   xmass1(j,ks)/xmass(npoint(j),ks))
537            else
538              xmassfract=1.
539            endif
540          end do
541
542          if (xmassfract.lt.0.0001) then   ! terminate all particles carrying less mass
543            itra1(j)=-999999999
544          endif
545
546  !        Sabine Eckhardt, June 2008
547  !        don't create depofield for backward runs
548          if (DRYDEP.AND.(ldirect.eq.1)) then
549            call drydepokernel(nclass(j),drydeposit,real(xtra1(j)), &
550                 real(ytra1(j)),nage,kp)
551            if (nested_output.eq.1) call drydepokernel_nest( &
552                 nclass(j),drydeposit,real(xtra1(j)),real(ytra1(j)), &
553                 nage,kp)
554          endif
555
556  ! Terminate trajectories that are older than maximum allowed age
557  !***************************************************************
558
559          if (abs(itra1(j)-itramem(j)).ge.lage(nageclass)) then
560            if (linit_cond.ge.1) &
561                 call initial_cond_calc(itime+lsynctime,j)
562            itra1(j)=-999999999
563          endif
564        endif
565
566      endif
567
568    end do
569
570  end do
571
572
573  ! Complete the calculation of initial conditions for particles not yet terminated
574  !*****************************************************************************
575
576  do j=1,numpart
577    if (linit_cond.ge.1) call initial_cond_calc(itime,j)
578  end do
579
580  if (ipout.eq.2) call partoutput(itime)     ! dump particle positions
581
582  if (linit_cond.ge.1) call initial_cond_output(itime)   ! dump initial cond. field
583
584  close(104)
585
586  ! De-allocate memory and end
587  !***************************
588
589  if (iflux.eq.1) then
590      deallocate(flux)
591  endif
592  if (OHREA.eqv..TRUE.) then
593      deallocate(OH_field,OH_field_height)
594  endif
595  if (ldirect.gt.0) then
596  deallocate(drygridunc,wetgridunc)
597  endif
598  deallocate(gridunc)
599  deallocate(xpoint1,xpoint2,ypoint1,ypoint2,zpoint1,zpoint2,xmass)
600  deallocate(ireleasestart,ireleaseend,npart,kindz)
601  deallocate(xmasssave)
602  if (nested_output.eq.1) then
603     deallocate(orooutn, arean, volumen)
604     if (ldirect.gt.0) then
605     deallocate(griduncn,drygriduncn,wetgriduncn)
606     endif
607  endif
608  deallocate(outheight,outheighthalf)
609  deallocate(oroout, area, volume)
610
611end subroutine timemanager
612
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG