source: flexpart.git/src/timemanager_mpi.f90 @ 5f9d14a

10.4.1_peseiGFS_025bugfixes+enhancementsdevrelease-10release-10.4.1scaling-bugunivie
Last change on this file since 5f9d14a was 5f9d14a, checked in by Espen Sollum ATMOS <eso@…>, 9 years ago

Updated wet depo scheme

  • Property mode set to 100644
File size: 30.6 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!  Changes Stefan Henne, Harald Sodemann, 2013-2014                          *
48!   added netcdf output code                                                 *
49!  Changes Espen Sollum 2014                                                 *
50!   MPI version                                                              *
51!   Variables uap,ucp,uzp,us,vs,ws,cbt now in module com_mod                 *
52!*****************************************************************************
53!                                                                            *
54! Variables:                                                                 *
55! dep                .true. if either wet or dry deposition is switched on   *
56! decay(maxspec) [1/s] decay constant for radioactive decay                  *
57! drydep             .true. if dry deposition is switched on                 *
58! ideltas [s]        modelling period                                        *
59! itime [s]          actual temporal position of calculation                 *
60! ldeltat [s]        time since computation of radioact. decay of depositions*
61! loutaver [s]       averaging period for concentration calculations         *
62! loutend [s]        end of averaging for concentration calculations         *
63! loutnext [s]       next time at which output fields shall be centered      *
64! loutsample [s]     sampling interval for averaging of concentrations       *
65! loutstart [s]      start of averaging for concentration calculations       *
66! loutstep [s]       time interval for which concentrations shall be         *
67!                    calculated                                              *
68! npoint(maxpart)    index, which starting point the trajectory has          *
69!                    starting positions of trajectories                      *
70! nstop              serves as indicator for fate of particles               *
71!                    in the particle loop                                    *
72! nstop1             serves as indicator for wind fields (see getfields)     *
73! memstat            additional indicator for wind fields (see getfields)    *
74! outnum             number of samples for each concentration calculation    *
75! prob               probability of absorption at ground due to dry          *
76!                    deposition                                              *
77! wetdep             .true. if wet deposition is switched on                 *
78! weight             weight for each concentration sample (1/2 or 1)         *
79! uap(maxpart),ucp(maxpart),uzp(maxpart) = random velocities due to          *
80!                    turbulence                                              *
81! us(maxpart),vs(maxpart),ws(maxpart) = random velocities due to inter-      *
82!                    polation                                                *
83! xtra1(maxpart), ytra1(maxpart), ztra1(maxpart) =                           *
84!                    spatial positions of trajectories                       *
85!                                                                            *
86! Constants:                                                                 *
87! maxpart            maximum number of trajectories                          *
88!                                                                            *
89!*****************************************************************************
90
91  use unc_mod
92  use point_mod
93  use xmass_mod
94  use flux_mod
95  use outg_mod
96  use oh_mod
97  use par_mod
98  use com_mod
99  use mpi_mod
100  use netcdf_output_mod, only: concoutput_netcdf,concoutput_nest_netcdf,&
101       &concoutput_surf_netcdf,concoutput_surf_nest_netcdf
102
103  implicit none
104
105  logical :: fc_mp=.true., fc_sync=.true.
106  logical :: reqv_state=.false. ! .true. if waiting for a MPI_Irecv to complete
107  integer :: j,ks,kp,l,n,itime=0,nstop,nstop1,memstat=0,mind
108! integer :: ksp
109  integer :: ip
110  integer :: loutnext,loutstart,loutend
111  integer :: ix,jy,ldeltat,itage,nage
112  integer :: i_nan=0,ii_nan,total_nan_intl=0  !added by mc to check instability in CBL scheme
113  real :: outnum,weight,prob(maxspec)
114  real :: decfact
115
116  real :: drydeposit(maxspec),gridtotalunc,wetgridtotalunc
117  real :: drygridtotalunc,xold,yold,zold,xmassfract
118!double precision xm(maxspec,maxpointspec_act),
119!    +                 xm_depw(maxspec,maxpointspec_act),
120!    +                 xm_depd(maxspec,maxpointspec_act)
121
122!open(88,file='TEST.dat')
123
124! Measure time spent in timemanager
125  if (mp_measure_time) call mpif_mtime('timemanager',0)
126
127! First output for time 0
128!************************
129
130  loutnext=loutstep/2
131  outnum=0.
132  loutstart=loutnext-loutaver/2
133  loutend=loutnext+loutaver/2
134
135
136!**********************************************************************
137! Loop over the whole modelling period in time steps of mintime seconds
138!**********************************************************************
139
140
141!  itime=0
142  if (lroot) then
143  !  write(*,45) itime,numpart*mp_partgroup_np,gridtotalunc,wetgridtotalunc,drygridtotalunc
144    write(*,46) float(itime)/3600,itime,numpart*mp_partgroup_np
145
146    if (verbosity.gt.0) then
147      write (*,*) 'timemanager> starting simulation'
148    end if
149  end if ! (lroot)
150
151  do itime=0,ideltas,lsynctime
152
153! Computation of wet deposition, OH reaction and mass transfer
154! between two species every lsynctime seconds
155! maybe wet depo frequency can be relaxed later but better be on safe side
156! wetdepo must be called BEFORE new fields are read in but should not
157! be called in the very beginning before any fields are loaded, or
158! before particles are in the system
159! Code may not be correct for decay of deposition
160! changed by Petra Seibert 9/02
161!********************************************************************
162
163    if (mp_dev_mode) write(*,*) 'myid, itime: ',mp_pid,itime
164   
165    if (wetdep .and. itime .ne. 0 .and. numpart .gt. 0) then
166      if (verbosity.gt.0) then
167        write (*,*) 'timemanager> call wetdepo'
168      endif
169
170      if (mp_measure_time) call mpif_mtime('wetdepo',0)
171       
172! readwind process skips this step
173      if (.not.(lmpreader.and.lmp_use_reader)) then
174        call wetdepo(itime,lsynctime,loutnext)
175      end if
176
177      if (mp_measure_time) call mpif_mtime('wetdepo',1)
178    end if
179
180    if (OHREA .and. itime .ne. 0 .and. numpart .gt. 0) then
181! readwind process skips this step
182      if (.not.(lmpreader.and.lmp_use_reader)) then
183        call ohreaction(itime,lsynctime,loutnext)
184      endif
185    end if
186
187    if (assspec .and. itime .ne. 0 .and. numpart .gt. 0) then
188      stop 'associated species not yet implemented!'
189!     call transferspec(itime,lsynctime,loutnext)
190    endif
191
192
193! compute convection for backward runs
194!*************************************
195
196    if ((ldirect.eq.-1).and.(lconvection.eq.1).and.(itime.lt.0)) then
197      if (verbosity.gt.0) then
198        write (*,*) 'timemanager> call convmix -- backward'
199      endif
200! readwind process skips this step
201      if (.not.(lmpreader.and.lmp_use_reader)) call convmix(itime)
202    endif
203
204! Get necessary wind fields if not available
205!*******************************************
206    if (verbosity.gt.0 .and. lmpreader) then
207      write (*,*) 'timemanager> call getfields'
208    endif
209
210    if (mp_measure_time) call mpif_mtime('getfields',0)
211
212    call getfields(itime,nstop1,memstat)
213
214    if (mp_measure_time) call mpif_mtime('getfields',1)
215
216! Broadcast fields to all MPI processes
217! Skip if all processes have called getfields or if no new fields
218!*****************************************************************
219
220! Version 1 (lmp_sync=.true.) uses a read-ahead process where send/recv is done
221! in sync at start of each new field time interval
222    if (lmp_sync.and.lmp_use_reader.and.memstat.gt.0) then
223      call mpif_gf_send_vars(memstat)
224      call mpif_gf_send_vars_nest(memstat)
225! Version 2  (lmp_sync=.false.) is also used whenever 2 new fields are read (in which
226! case async send/recv is impossible.
227    else if (.not.lmp_sync.and.lmp_use_reader.and.memstat.ge.32) then
228      call mpif_gf_send_vars(memstat)
229      call mpif_gf_send_vars_nest(memstat)
230    end if
231
232! Version 2 (lmp_sync=.false.) is for holding three fields in memory. Uses a
233! read-ahead process where sending/receiving of the 3rd fields is done in
234! the background in parallel with performing computations with fields 1&2
235!********************************************************************************
236    if (.not.lmp_sync) then
237   
238! READER PROCESS:
239      if (memstat.gt.0..and.memstat.lt.32.and.lmp_use_reader.and.lmpreader) then
240        call mpif_gf_send_vars_async(memstat)
241      end if
242
243! COMPLETION CHECK:
244! Issued at start of each new field period.
245      if (memstat.ne.0.and.memstat.lt.32.and.lmp_use_reader) then
246! TODO: z0(7) changes with time, so should be dimension (numclass,2) to
247! allow transfer of the future value in the background
248        call MPI_Bcast(z0,numclass,mp_pp,id_read,MPI_COMM_WORLD,mp_ierr)
249        call mpif_gf_request
250      end if
251
252! RECVEIVING PROCESS(ES):
253      ! eso TODO: at this point we do not know if clwc/ciwc will be available
254      ! at next time step. Issue receive request anyway, cancel at mpif_gf_request
255      if (memstat.gt.0.and.lmp_use_reader.and..not.lmpreader) then
256        call mpif_gf_recv_vars_async(memstat)
257      end if
258
259    end if
260
261!*******************************************************************************
262
263    if (lmpreader.and.nstop1.gt.1) stop 'NO METEO FIELDS AVAILABLE'
264
265! Reader process goes back to top of time loop (unless simulation end)
266!*********************************************************************
267
268    if (lmpreader.and.lmp_use_reader) then
269      if (itime.lt.ideltas) then
270        cycle
271      else
272        goto 999
273      end if
274    end if
275
276
277! Get hourly OH fields if not available
278!****************************************************
279    if (OHREA) then
280      if (verbosity.gt.0) then
281        write (*,*) 'timemanager> call gethourlyOH'
282      endif
283      call gethourlyOH(itime)
284    endif
285
286
287! Release particles
288!******************
289
290    if (verbosity.gt.0.and.lroot) then
291      write (*,*) 'timemanager>  Release particles'
292    endif
293
294    if (mdomainfill.ge.1) then
295      if (itime.eq.0) then
296        if (verbosity.gt.0) then
297          write (*,*) 'timemanager>  call init_domainfill'
298        endif
299        call init_domainfill
300      else
301        if (verbosity.gt.0.and.lroot) then
302          write (*,*) 'timemanager>  call boundcond_domainfill'
303        endif
304        call boundcond_domainfill(itime,loutend)
305      endif
306    else
307      if (verbosity.gt.0.and.lroot) then
308        print*,'call releaseparticles' 
309      endif
310      call releaseparticles(itime)
311    endif
312
313
314! Compute convective mixing for forward runs
315! for backward runs it is done before next windfield is read in
316!**************************************************************
317
318    if ((ldirect.eq.1).and.(lconvection.eq.1)) then
319      if (verbosity.gt.0) then
320        write (*,*) 'timemanager> call convmix -- forward'
321      endif
322      call convmix(itime)
323    endif
324
325! If middle of averaging period of output fields is reached, accumulated
326! deposited mass radioactively decays
327!***********************************************************************
328
329    if (DEP.and.(itime.eq.loutnext).and.(ldirect.gt.0)) then
330      do ks=1,nspec
331        do kp=1,maxpointspec_act
332          if (decay(ks).gt.0.) then
333            do nage=1,nageclass
334              do l=1,nclassunc
335! Mother output grid
336                do jy=0,numygrid-1
337                  do ix=0,numxgrid-1
338                    wetgridunc(ix,jy,ks,kp,l,nage)= &
339                         wetgridunc(ix,jy,ks,kp,l,nage)* &
340                         exp(-1.*outstep*decay(ks))
341                    drygridunc(ix,jy,ks,kp,l,nage)= &
342                         drygridunc(ix,jy,ks,kp,l,nage)* &
343                         exp(-1.*outstep*decay(ks))
344                  end do
345                end do
346! Nested output grid
347                if (nested_output.eq.1) then
348                  do jy=0,numygridn-1
349                    do ix=0,numxgridn-1
350                      wetgriduncn(ix,jy,ks,kp,l,nage)= &
351                           wetgriduncn(ix,jy,ks,kp,l,nage)* &
352                           exp(-1.*outstep*decay(ks))
353                      drygriduncn(ix,jy,ks,kp,l,nage)= &
354                           drygriduncn(ix,jy,ks,kp,l,nage)* &
355                           exp(-1.*outstep*decay(ks))
356                    end do
357                  end do
358                endif
359              end do
360            end do
361          endif
362        end do
363      end do
364    endif
365
366
367!!! CHANGE: These lines may be switched on to check the conservation
368!!! of mass within FLEXPART
369!   if (itime.eq.loutnext) then
370!   do 247 ksp=1, nspec
371!   do 247 kp=1, maxpointspec_act
372!47         xm(ksp,kp)=0.
373
374!   do 249 ksp=1, nspec
375!     do 249 j=1,numpart
376!          if (ioutputforeachrelease.eq.1) then
377!            kp=npoint(j)
378!          else
379!            kp=1
380!          endif
381!       if (itra1(j).eq.itime) then
382!          xm(ksp,kp)=xm(ksp,kp)+xmass1(j,ksp)
383!         write(*,*) 'xmass: ',xmass1(j,ksp),j,ksp,nspec
384!       endif
385!49     continue
386!  do 248 ksp=1,nspec
387!  do 248 kp=1,maxpointspec_act
388!  xm_depw(ksp,kp)=0.
389!  xm_depd(ksp,kp)=0.
390!     do 248 nage=1,nageclass
391!       do 248 ix=0,numxgrid-1
392!         do 248 jy=0,numygrid-1
393!           do 248 l=1,nclassunc
394!              xm_depw(ksp,kp)=xm_depw(ksp,kp)
395!    +                  +wetgridunc(ix,jy,ksp,kp,l,nage)
396!48                 xm_depd(ksp,kp)=xm_depd(ksp,kp)
397!    +                  +drygridunc(ix,jy,ksp,kp,l,nage)
398!             do 246 ksp=1,nspec
399!46                    write(88,'(2i10,3e12.3)')
400!    +              itime,ksp,(xm(ksp,kp),kp=1,maxpointspec_act),
401!    +                (xm_depw(ksp,kp),kp=1,maxpointspec_act),
402!    +                (xm_depd(ksp,kp),kp=1,maxpointspec_act)
403!  endif
404!!! CHANGE
405
406
407
408
409! Check whether concentrations are to be calculated
410!**************************************************
411
412    if ((ldirect*itime.ge.ldirect*loutstart).and. &
413         (ldirect*itime.le.ldirect*loutend)) then ! add to grid
414      if (mod(itime-loutstart,loutsample).eq.0) then
415
416! If we are exactly at the start or end of the concentration averaging interval,
417! give only half the weight to this sample
418!*****************************************************************************
419
420        if ((itime.eq.loutstart).or.(itime.eq.loutend)) then
421          weight=0.5
422        else
423          weight=1.0
424        endif
425        outnum=outnum+weight
426
427        call conccalc(itime,weight)
428
429      endif
430
431! :TODO: MPI output of particle positions;  each process sequentially
432!   access the same file
433      if ((mquasilag.eq.1).and.(itime.eq.(loutstart+loutend)/2)) &
434           call partoutput_short(itime)    ! dump particle positions in extremely compressed format
435
436
437! Output and reinitialization of grid
438! If necessary, first sample of new grid is also taken
439!*****************************************************
440
441      if ((itime.eq.loutend).and.(outnum.gt.0.)) then
442        if ((iout.le.3.).or.(iout.eq.5)) then
443
444! MPI: Root process collects/sums grids
445!**************************************
446          call mpif_tm_reduce_grid
447
448          if (surf_only.ne.1) then
449            if (lroot) then
450              if (lnetcdfout.eq.1) then
451                call concoutput_netcdf(itime,outnum,gridtotalunc,wetgridtotalunc,&
452                     &drygridtotalunc)
453              else
454                call concoutput(itime,outnum,gridtotalunc,wetgridtotalunc,drygridtotalunc)
455              endif
456            else
457              gridunc(:,:,:,:,:,:,:)=0.
458            end if
459          else
460            if (lroot) then
461              if (lnetcdfout.eq.1) then
462
463                call concoutput_surf_netcdf(itime,outnum,gridtotalunc,wetgridtotalunc,&
464                     &drygridtotalunc)
465              else
466                call concoutput_surf(itime,outnum,gridtotalunc,wetgridtotalunc,drygridtotalunc)
467              end if
468            else
469              gridunc(:,:,:,:,:,:,:)=0.
470            endif
471          endif
472
473! :TODO: Correct calling of conc_surf above?
474
475!   call concoutput_surf(itime,outnum,gridtotalunc,wetgridtotalunc,drygridtotalunc)
476! endif
477
478          if (nested_output.eq.1) then
479
480! MPI: Root process collects/sums nested grids
481!*********************************************
482            call mpif_tm_reduce_grid_nest
483
484            if (lnetcdfout.eq.0) then
485              if (surf_only.ne.1) then
486
487                if (lroot) then
488                  call concoutput_nest(itime,outnum)
489                else
490                  griduncn(:,:,:,:,:,:,:)=0.
491                end if
492
493              else  ! :TODO: check for zeroing in the netcdf module
494                call concoutput_surf_nest(itime,outnum)
495
496              end if
497
498            else
499
500              if (surf_only.ne.1) then
501                if (lroot) then             
502                  call concoutput_nest_netcdf(itime,outnum)
503                else
504                  griduncn(:,:,:,:,:,:,:)=0.
505                end if
506              else
507                if (lroot) then
508                  call concoutput_surf_nest_netcdf(itime,outnum)
509                else
510                  griduncn(:,:,:,:,:,:,:)=0.
511                end if
512              endif
513
514
515            end if
516          end if
517
518          outnum=0.
519        endif
520        if ((iout.eq.4).or.(iout.eq.5)) call plumetraj(itime)
521        if (iflux.eq.1) call fluxoutput(itime)
522        if (lroot) write(*,45) itime,numpart*mp_partgroup_np,gridtotalunc,&
523             &wetgridtotalunc,drygridtotalunc
524!      if (lroot) write(*,46) float(itime)/3600,itime,numpart*mp_partgroup_np
52545      format(i13,' SECONDS SIMULATED: ',i13, ' PARTICLES:    Uncertainty: ',3f7.3)
52646      format(' Simulated ',f7.1,' hours (',i13,' s), ',i13, ' particles')
527        if (ipout.ge.1) then
528          do ip=0, mp_partgroup_np-1
529            if (ip.eq.mp_partid) call partoutput(itime) ! dump particle positions
530            call mpif_mpi_barrier
531          end do
532        end if
533
534        loutnext=loutnext+loutstep
535        loutstart=loutnext-loutaver/2
536        loutend=loutnext+loutaver/2
537        if (itime.eq.loutstart) then
538          weight=0.5
539          outnum=outnum+weight
540          call conccalc(itime,weight)
541        endif
542
543
544
545! Check, whether particles are to be split:
546! If so, create new particles and attribute all information from the old
547! particles also to the new ones; old and new particles both get half the
548! mass of the old ones
549!************************************************************************
550       
551        if (ldirect*itime.ge.ldirect*itsplit) then
552          n=numpart
553          do j=1,numpart
554            if (ldirect*itime.ge.ldirect*itrasplit(j)) then
555!                if (n.lt.maxpart) then
556              if (n.lt.maxpart_mpi) then
557                n=n+1
558                itrasplit(j)=2*(itrasplit(j)-itramem(j))+itramem(j)
559                itrasplit(n)=itrasplit(j)
560                itramem(n)=itramem(j)
561                itra1(n)=itra1(j)
562                idt(n)=idt(j)
563                npoint(n)=npoint(j)
564                nclass(n)=nclass(j)
565                xtra1(n)=xtra1(j)
566                ytra1(n)=ytra1(j)
567                ztra1(n)=ztra1(j)
568                uap(n)=uap(j)
569                ucp(n)=ucp(j)
570                uzp(n)=uzp(j)
571                us(n)=us(j)
572                vs(n)=vs(j)
573                ws(n)=ws(j)
574                cbt(n)=cbt(j)
575                do ks=1,nspec
576                  xmass1(j,ks)=xmass1(j,ks)/2.
577                  xmass1(n,ks)=xmass1(j,ks)
578                end do
579              endif
580            endif
581          end do
582          numpart=n
583        endif
584      endif
585    endif
586   
587
588    if (itime.eq.ideltas) exit         ! almost finished
589
590! Compute interval since radioactive decay of deposited mass was computed
591!************************************************************************
592
593    if (itime.lt.loutnext) then
594      ldeltat=itime-(loutnext-loutstep)
595    else                                  ! first half of next interval
596      ldeltat=itime-loutnext
597    endif
598
599
600! Loop over all particles
601!************************
602    if (mp_measure_time) call mpif_mtime('partloop1',0)
603
604!--------------------------------------------------------------------------------
605! various variables for testing reason of CBL scheme, by mc
606    well_mixed_vector=0. !erase vector to test well mixed condition: modified by mc
607    well_mixed_norm=0.   !erase normalization to test well mixed condition: modified by mc
608    avg_ol=0.
609    avg_wst=0.
610    avg_h=0.
611    avg_air_dens=0.  !erase vector to obtain air density at particle positions: modified by mc
612!--------------------------------------------------------------------------------
613
614    do j=1,numpart
615
616! If integration step is due, do it
617!**********************************
618
619      if (itra1(j).eq.itime) then
620
621        if (ioutputforeachrelease.eq.1) then
622          kp=npoint(j)
623        else
624          kp=1
625        endif
626! Determine age class of the particle
627        itage=abs(itra1(j)-itramem(j))
628        do nage=1,nageclass
629          if (itage.lt.lage(nage)) exit
630        end do
631
632! Initialize newly released particle
633!***********************************
634
635        if ((itramem(j).eq.itime).or.(itime.eq.0)) &
636             call initialize(itime,idt(j),uap(j),ucp(j),uzp(j), &
637             us(j),vs(j),ws(j),xtra1(j),ytra1(j),ztra1(j),cbt(j))
638
639! Memorize particle positions
640!****************************
641
642        xold=xtra1(j)
643        yold=ytra1(j)
644        zold=ztra1(j)
645
646! Integrate Lagevin equation for lsynctime seconds
647!*************************************************
648
649        mp_advance_wtime_beg = mpi_wtime()
650
651        call advance(itime,npoint(j),idt(j),uap(j),ucp(j),uzp(j), &
652             us(j),vs(j),ws(j),nstop,xtra1(j),ytra1(j),ztra1(j),prob, &
653             cbt(j))
654
655        mp_advance_wtime_end = mpi_wtime()
656        mp_advance_wtime_total = mp_advance_wtime_total + (mp_advance_wtime_end - &
657             & mp_advance_wtime_beg)
658
659
660! Calculate the gross fluxes across layer interfaces
661!***************************************************
662
663        if (iflux.eq.1) call calcfluxes(nage,j,xold,yold,zold)
664
665
666! Determine, when next time step is due
667! If trajectory is terminated, mark it
668!**************************************
669
670        if (nstop.gt.1) then
671          if (linit_cond.ge.1) call initial_cond_calc(itime,j)
672          itra1(j)=-999999999
673        else
674          itra1(j)=itime+lsynctime
675
676
677! Dry deposition and radioactive decay for each species
678! Also check maximum (of all species) of initial mass remaining on the particle;
679! if it is below a threshold value, terminate particle
680!*****************************************************************************
681
682          xmassfract=0.
683          do ks=1,nspec
684            if (decay(ks).gt.0.) then             ! radioactive decay
685              decfact=exp(-real(abs(lsynctime))*decay(ks))
686            else
687              decfact=1.
688            endif
689
690            if (DRYDEPSPEC(ks)) then        ! dry deposition
691              drydeposit(ks)=xmass1(j,ks)*prob(ks)*decfact
692              xmass1(j,ks)=xmass1(j,ks)*(1.-prob(ks))*decfact
693              if (decay(ks).gt.0.) then   ! correct for decay (see wetdepo)
694                drydeposit(ks)=drydeposit(ks)* &
695                     exp(real(abs(ldeltat))*decay(ks))
696              endif
697            else                           ! no dry deposition
698              xmass1(j,ks)=xmass1(j,ks)*decfact
699            endif
700
701
702            if (mdomainfill.eq.0) then
703              if (xmass(npoint(j),ks).gt.0.) &
704                   xmassfract=max(xmassfract,real(npart(npoint(j)))* &
705                   xmass1(j,ks)/xmass(npoint(j),ks))
706            else
707              xmassfract=1.
708            endif
709          end do
710
711          if (xmassfract.lt.0.0001) then   ! terminate all particles carrying less mass
712            itra1(j)=-999999999
713          endif
714
715!        Sabine Eckhardt, June 2008
716!        don't create depofield for backward runs
717          if (DRYDEP.AND.(ldirect.eq.1)) then
718            call drydepokernel(nclass(j),drydeposit,real(xtra1(j)), &
719                 real(ytra1(j)),nage,kp)
720            if (nested_output.eq.1) call drydepokernel_nest( &
721                 nclass(j),drydeposit,real(xtra1(j)),real(ytra1(j)), &
722                 nage,kp)
723          endif
724
725! Terminate trajectories that are older than maximum allowed age
726!***************************************************************
727
728          if (abs(itra1(j)-itramem(j)).ge.lage(nageclass)) then
729            if (linit_cond.ge.1) &
730                 call initial_cond_calc(itime+lsynctime,j)
731            itra1(j)=-999999999
732          endif
733        endif
734
735      endif
736
737    end do ! j=1, numpart
738
739    if(mp_measure_time) call mpif_mtime('partloop1',1)
740
741
742! Added by mc: counter of "unstable" particle velocity during a time scale
743!   of maximumtl=20 minutes (defined in com_mod)
744
745    total_nan_intl=0
746    i_nan=i_nan+1 ! added by mc to count nan during a time of maxtl (i.e. maximum tl fixed here to 20 minutes, see com_mod)
747    sum_nan_count(i_nan)=nan_count
748    if (i_nan > maxtl/lsynctime) i_nan=1 !lsynctime must be <= maxtl
749    do ii_nan=1, (maxtl/lsynctime)
750      total_nan_intl=total_nan_intl+sum_nan_count(ii_nan)
751    end do
752
753! Output to keep track of the numerical instabilities in CBL simulation
754! and if they are compromising the final result (or not):
755    if (cblflag.eq.1) print *,j,itime,'nan_synctime',nan_count,'nan_tl',total_nan_intl 
756
757! TODO: delete for release version?
758!!-------------------------------------------------------------------------------
759! These lines below to test the well-mixed condition, modified by  mc, not to
760! be included in final release:
761!
762! if (itime.eq.0) then
763! open(551,file='/home/mc/test_cbl/out/WELLMIXEDTEST_CBL_lonlat_9_33_100_3hours_3htp_cd.DAT')
764! open(552,file='/home/mc/test_cbl/out/avg_ol_h_wst_lonlat_9_33_100_3hours_3htp_cd.DAT')
765! end if
766! write(552,'(5F16.7)')itime*1./3600.,avg_wst/well_mixed_norm,avg_ol/well_mixed_norm,avg_h/well_mixed_norm
767! do j=1,25
768!      !write(551,*))itime*1.,h_well/50.*j,well_mixed_vector(j)/well_mixed_norm*50.
769!     avg_air_dens(j)=avg_air_dens(j)/well_mixed_vector(j)
770!     write(551,'(5F16.7)')itime*1.,h_well/25.*j,well_mixed_vector(j)/well_mixed_norm*25.,avg_air_dens(j),0.04*j
771! end do
772!!------------------------------------------------------------------------------
773
774  end do ! itime=0,ideltas,lsynctime
775
776
777! Complete the calculation of initial conditions for particles not yet terminated
778!*****************************************************************************
779
780! eso :TODO: this not implemented yet (transfer particles to PID 0 or rewrite)
781! the tools to do this are already in mpi_mod.f90
782  if (lroot) then
783    do j=1,numpart
784      if (linit_cond.ge.1) call initial_cond_calc(itime,j)
785    end do
786  end if
787
788
789  if (ipout.eq.2) then
790! MPI process 0 creates the file, the other processes append to it
791    do ip=0, mp_partgroup_np-1
792      if (ip.eq.mp_partid) then
793        !if (mp_dbg_mode) write(*,*) 'call partoutput(itime), proc, mp_partid',ip,mp_partid
794        call partoutput(itime)    ! dump particle positions
795      end if
796      call mpif_mpi_barrier
797    end do
798  end if
799
800! eso :TODO: MPI
801  if (linit_cond.ge.1.and.lroot) call initial_cond_output(itime)   ! dump initial cond. field
802
803
804! De-allocate memory and end
805!***************************
806
807999 if (iflux.eq.1) then
808    deallocate(flux)
809  endif
810  if (OHREA) then
811    deallocate(OH_field,OH_hourly,lonOH,latOH,altOH)
812  endif
813  if (ldirect.gt.0) then
814    deallocate(drygridunc,wetgridunc)
815  endif
816  deallocate(gridunc)
817  deallocate(xpoint1,xpoint2,ypoint1,ypoint2,zpoint1,zpoint2,xmass)
818  deallocate(ireleasestart,ireleaseend,npart,kindz)
819  deallocate(xmasssave)
820  if (nested_output.eq.1) then
821    deallocate(orooutn, arean, volumen)
822    if (ldirect.gt.0) then
823      deallocate(griduncn,drygriduncn,wetgriduncn)
824    endif
825  endif
826  deallocate(outheight,outheighthalf)
827  deallocate(oroout, area, volume)
828
829  if (mp_measure_time) call mpif_mtime('timemanager',1)
830
831end subroutine timemanager
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG