File: timemanager.f

package info (click to toggle)
flextra 5.0-2.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 860 kB
  • ctags: 402
  • sloc: fortran: 6,987; makefile: 55; sh: 17
file content (331 lines) | stat: -rw-r--r-- 13,991 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
      subroutine timemanager()                                  

********************************************************************************
*                                                                              *
* Handles the computation of trajectories, i.e. determines which               *
* trajectories have to be computed at what time.                               *
*                                                                              *
* Pointers (field numb(maxtra) are used to keep track of the trajectories.     *
* The pointers are kept sorted in the order of the next necessary time step,   *
* i.e., numb(1) points to the first trajectory that needs a time step.         *
* After doing the time step, the pointers are resorted, e.g., numb(2)          *
* changes to numb(1), numb(3) to numb(2), etc. Numb(1) is inserted between     *
* those two pointers, which need a time step before and after numb(1).         *
*                                                                              *
*                                                                              *
*     Author: A. Stohl                                                         *
*                                                                              *
*     6 February 1994                                                          *
*                                                                              *
********************************************************************************
*                                                                              *
* Variables:                                                                   *
* ideltas [s]        modelling period                                          *
* init               .true. for first time step of trajectory, false .else.    *
* interv [s]         interval between two trajectory starting times            *
* itime [s]          actual temporal position of calculation                   *
* ittra(maxtra,maxtime) temporal positions of trajectories                     *
* kind(maxtra)       type of trajectory (e.g. isobaric, 3-d, model layers,..)  *
* kindz(maxtra)      unit of height coordinate (1:masl, 2:magl, 3:hPa)         *
* ldirect            Temporal direction of trajectories (-1=backward,1=forward)*
* lentra             temporal length of one trajectory                         *
* levmem(maxtra) [K] height of isentropic trajectories                         *
* minstep            minimum time step (to prevent exceedance of dimensions)   *
* nextflight [s]     next time, initialization of FLIGHT trajectories is due   *
* npoint(maxtra)     index, which starting point the trajectory has            *
* nstop              = greater than 0 when trajectory calculation is finished  *
* ntstep [s]         time step of integration scheme                           *
* nttra(maxtra)      number of time steps which are already computed           *
* numb(maxtra)       pointer, which allows the identification of trajectories  *
* number             help variable                                             *
* numtra             actual number of trajectories in memory                   *
* xpoint(maxpoint), ypoint(maxpoint),zpoint(maxpoint) =                        *
* xpoint(maxpoint), ypoint(maxpoint),zpoint(maxpoint) =                        *
*                    starting positions of trajectories                        *
* xtra(maxtra,maxtime), ytra(maxtra,maxtime), ztra(maxtra,maxtime) =           *
*                    spatial positions of trajectories                         *
*                                                                              *
* Constants:                                                                   *
* maxtra             maximum number of trajectories                            *
* maxtime            maximum number of time steps                              *
*                                                                              *
********************************************************************************

      include 'includepar'
      include 'includecom'

      integer i,j,itime,ntstep,nstop(maxtra),lhelp,minstep,numb(maxtra)
      integer number,idummy,ldat,ltim,ninterv1,ninterv2,ninterv3
      real levmem(maxtra),gasdev
      logical init,unc,error
      double precision juldate
      save idummy

      data idummy/-7/


      do 5 i=1,maxtra
5       nttra(i)=0
      numtra=0                                      ! first: no trajectories


C Loop over the whole modelling period in time steps of seconds
***************************************************************

      do 10 itime=0,ideltas,ldirect
        if (mod(itime,3600).eq.0) write(*,*) itime,' SECONDS SIMULATED'


C Check whether some trajectories have already finished. If so, call output
C and make memory available for new trajectory.
***************************************************************************

        if (numtra.gt.0) then

          i=1
33        continue
          number=numb(i)
       
          if (abs(ittra(number,nttra(number))).gt.abs(itime)) goto 37
          if ((nstop(number).gt.0).and.               ! trajectory terminated
     +       (ittra(number,nttra(number)).eq.itime)) then     ! output time
c           if (modecet.ne.2) then                    ! don't make output for CETs
              call trajout(number,nstop(number))      ! output of trajectory
              nttra(number)=0                         ! reinitialize
              do 35 j=i,numtra-1                      ! resort the pointers
35              numb(j)=numb(j+1)
c           endif
            numtra=numtra-1                           ! forget one trajectory
            i=i-1
          endif
          if (i.lt.numtra) then
            i=i+1
            goto 33
          else
            goto 37 
          endif

37        continue
        endif



C Check whether new trajectories have to be started
C 1nd if: check if time within modeling period
C 2nd if: check if the interval interv has passed by (for NORMAL
C         trajectories) or if a FLIGHT traj. is due to be started
*****************************************************************

        if (abs(itime).le.abs(ideltas-lentra)) then
          if (modecet.eq.3) then       ! FLIGHT mode
41          continue
            if ((nextflight.eq.itime).and.(numtra.lt.maxtra)) then
              do 43 i=numtra,1,-1         ! shift pointers
43              numb(i+1)=numb(i)
              numtra=numtra+1             ! increase number of traj.

              j=1                         ! initialize FLIGHT traj.
42            continue
              if (nttra(j).eq.0) then
                numb(1)=j
                npoint(j)=1
                levmem(j)=zpoint(1)
                xtra(j,1)=xpoint(1)
                ytra(j,1)=ypoint(1)
                ztra(j,1)=zpoint(1)
                ittra(j,1)=itime
                nttra(j)=1
                kind(j)=kind(1)
                kindz(j)=kindz(1)
              else 
                j=j+1
                if (j.gt.maxtra) stop 'timemanager: too many trajectorie
     +s. Increase parameter maxtra and re-start'
                goto 42
              endif

C Read the next FLIGHT traj. 
****************************

              read(unitpoin,*,err=15,end=15) ldat,ltim
              read(unitpoin,*,err=15,end=15) xpoint(1)
              read(unitpoin,*,err=15,end=15) ypoint(1)
              read(unitpoin,*,err=15,end=15) zpoint(1)
              read(unitpoin,*,err=15,end=15)
              nextflight=nint(sngl(juldate(ldat,ltim)-bdate)*86400.)
              call coordtrafo(error)
              if (error) stop
              call subtractoro()
              if (kindz(1).eq.3) zpoint(1)=zpoint(1)*100.

              goto 41
            endif

          else if (mod(itime,interv).eq.0) then !non-FLIGHT mode, initialization due
            do 40 i=numtra,1,-1                       ! shift pointers
40            numb(i+numpoint)=numb(i)
            numtra=numtra+numpoint                    ! increase number of traj.


C Initialize new trajectories
*****************************

            j=1
            do 50 i=1,numpoint        ! search for available memory
55            continue
              if (nttra(j).eq.0) then
                numb(i)=j
                npoint(j)=i
                levmem(j)=zpoint(i)
                xtra(j,1)=xpoint(i)
                ytra(j,1)=ypoint(i)
                ztra(j,1)=zpoint(i)
                ittra(j,1)=itime
                nttra(j)=1
                kind(j)=kind(i)
                kindz(j)=kindz(i)
                randerroru(j)=gasdev(idummy)*epsu
                randerrorv(j)=gasdev(idummy)*epsv
                randerrorw(j)=gasdev(idummy)*epsw
              else 
                j=j+1
                goto 55
              endif
50            continue

          endif
        endif



C Check whether a time step of the first trajectory is necessary
****************************************************************

15      continue
        if (numtra.gt.0) then
        
        number=numb(1)

        if (ittra(number,nttra(number)).eq.itime) then

C minstep is the minimum possible time step. It is necessary to 
C guarantee that the sum of all time steps along the trajectory
C is smaller than maxtime (otherwise exceedance of dimensions).
***************************************************************

          lhelp=itime-ittra(number,1)         ! "age" of trajectory
          minstep=abs(lentra-lhelp)/(maxtime-nttra(number))+1


C Mark first time step of trajectory with variable init=.TRUE.
**************************************************************

          if (nttra(number).eq.1) then
            init=.true.
          else
            init=.false.
          endif


C Determine whether current trajectory is an uncertainty trajectory
*******************************************************************

          if (compoint(npoint(number))(41:41).eq.'U') then
            unc=.TRUE.
          else
            unc=.FALSE.
          endif
           

C Calculate the next step of the trajectory
*******************************************

          call petters(minstep,lhelp,itime,xtra(number,nttra(number)),
     +    ytra(number,nttra(number)),ztra(number,nttra(number)),
     +    ptra(number,nttra(number)),htra(number,nttra(number)),
     +    qqtra(number,nttra(number)),pvtra(number,nttra(number)),
     +    thtra(number,nttra(number)),
     +    xtra(number,nttra(number)+1),ytra(number,nttra(number)+1),
     +    ztra(number,nttra(number)+1),ptra(number,nttra(number)+1),
     +    htra(number,nttra(number)+1),qqtra(number,nttra(number)+1),
     +    pvtra(number,nttra(number)+1),thtra(number,nttra(number)+1),
     +    ntstep,nstop(number),
     +    levmem(number),init,kind(number),kindz(number),unc,
     +    randerroru(number),randerrorv(number),randerrorw(number))

          ittra(number,nttra(number)+1)=ittra(number,nttra(number))+
     +    ntstep

          nttra(number)=nttra(number)+1         ! one more time step


C If output is only due with constant time steps, disregard all points
C not needed for interpolation: delete previous time step
**********************************************************************

          if ((inter.eq.1).and.(nttra(number).ge.3)) then
            ninterv1=abs(ittra(number,nttra(number))-ittra(number,1))/
     +      interstep
            ninterv2=abs(ittra(number,nttra(number)-1)-ittra(number,1))/
     +      interstep
            ninterv3=abs(ittra(number,nttra(number)-2)-ittra(number,1))/
     +      interstep
            if ((ninterv1.eq.ninterv2).and.(ninterv1.eq.ninterv3)) then
              ittra(number,nttra(number)-1)=ittra(number,nttra(number))
              xtra(number,nttra(number)-1)=xtra(number,nttra(number))
              ytra(number,nttra(number)-1)=ytra(number,nttra(number))
              ztra(number,nttra(number)-1)=ztra(number,nttra(number))
              ptra(number,nttra(number)-1)=ptra(number,nttra(number))
              htra(number,nttra(number)-1)=htra(number,nttra(number))
              qqtra(number,nttra(number)-1)=qqtra(number,nttra(number))
              pvtra(number,nttra(number)-1)=pvtra(number,nttra(number))
              thtra(number,nttra(number)-1)=thtra(number,nttra(number))
              nttra(number)=nttra(number)-1
            endif
          endif

C If field dimension is reached, trajectory has to be terminated
****************************************************************

          if (nttra(number).eq.maxtime) nstop(number)=5


C If trajectory has ended, give the next time step the time of normal
C length of trajectory and wait for output of trajectory
*********************************************************************

          if (nstop(number).gt.0) then
            ittra(number,nttra(number))=ittra(number,1)+lentra
          endif


C Shift the trajectories in a way that the current trajectory can be
C inserted at the right position.
C The position is determined by the time, when the next integration step
C is necessary.
*************************************************************************

          do 20 i=1,numtra-1
            if (abs(ittra(numb(i+1),nttra(numb(i+1)))).lt.
     +      abs(ittra(number,nttra(number)))) then
              numb(i)=numb(i+1)
            else
              numb(i)=number                      ! insert the pointer
              goto 15                             ! leave loop
            endif
20          continue

C The next statement can only be reached, when the current trajectory is the
C last one that needs an integration step.
****************************************************************************

          numb(numtra)=number
          goto 15                                 ! check next trajectory
        endif
        endif


10     continue

      return
      end