source: codes/icosagcm/branches/SATURN_DYNAMICO/ICOSAGCM/src/timeloop_gcm.f90 @ 245

Last change on this file since 245 was 221, checked in by ymipsl, 10 years ago

Creating temporary dynamico/lmdz/saturn branche

YM

File size: 18.8 KB
Line 
1MODULE timeloop_gcm_mod
2  USE transfert_mod
3  USE icosa
4  PRIVATE
5 
6  PUBLIC :: init_timeloop, timeloop
7
8  INTEGER, PARAMETER :: euler=1, rk4=2, mlf=3
9  INTEGER, PARAMETER :: itau_sync=10
10
11  TYPE(t_message),SAVE :: req_ps0, req_mass0, req_theta_rhodz0, req_u0, req_q0
12
13  TYPE(t_field),POINTER,SAVE :: f_q(:)
14  TYPE(t_field),POINTER,SAVE :: f_rhodz(:), f_mass(:), f_massm1(:), f_massm2(:), f_dmass(:)
15  TYPE(t_field),POINTER,SAVE :: f_phis(:), f_ps(:),f_psm1(:), f_psm2(:), f_dps(:)
16  TYPE(t_field),POINTER,SAVE :: f_u(:),f_um1(:),f_um2(:), f_du(:)
17  TYPE(t_field),POINTER,SAVE :: f_theta_rhodz(:),f_theta_rhodzm1(:),f_theta_rhodzm2(:), f_dtheta_rhodz(:)
18  TYPE(t_field),POINTER,SAVE :: f_hflux(:), f_wflux(:), f_hfluxt(:), f_wfluxt(:) 
19
20  INTEGER,SAVE :: nb_stage, matsuno_period, scheme   
21!$OMP THREADPRIVATE(nb_stage, matsuno_period, scheme)
22
23CONTAINS
24 
25  SUBROUTINE init_timeloop
26  USE icosa
27  USE dissip_gcm_mod
28  USE caldyn_mod
29  USE etat0_mod
30  USE disvert_mod
31  USE guided_mod
32  USE advect_tracer_mod
33  USE physics_mod
34  USE mpipara
35  USE omp_para
36  USE trace
37  USE transfert_mod
38  USE check_conserve_mod
39  USE output_field_mod
40  USE write_field
41  IMPLICIT NONE
42
43    CHARACTER(len=255) :: def
44
45
46   IF (xios_output) itau_out=1
47   IF (.NOT. enable_io) itau_out=HUGE(itau_out)
48
49! Time-independant orography
50    CALL allocate_field(f_phis,field_t,type_real,name='phis')
51! Trends
52    CALL allocate_field(f_du,field_u,type_real,llm,name='du')
53    CALL allocate_field(f_dtheta_rhodz,field_t,type_real,llm,name='dtheta_rhodz')
54! Model state at current time step (RK/MLF/Euler)
55    CALL allocate_field(f_ps,field_t,type_real, name='ps')
56    CALL allocate_field(f_mass,field_t,type_real,llm,name='mass')
57    CALL allocate_field(f_u,field_u,type_real,llm,name='u')
58    CALL allocate_field(f_theta_rhodz,field_t,type_real,llm,name='theta_rhodz')
59! Model state at previous time step (RK/MLF)
60    CALL allocate_field(f_um1,field_u,type_real,llm,name='um1')
61    CALL allocate_field(f_theta_rhodzm1,field_t,type_real,llm,name='theta_rhodzm1')
62! Tracers
63    CALL allocate_field(f_q,field_t,type_real,llm,nqtot)
64    CALL allocate_field(f_rhodz,field_t,type_real,llm,name='rhodz')
65! Mass fluxes
66    CALL allocate_field(f_hflux,field_u,type_real,llm)    ! instantaneous mass fluxes
67    CALL allocate_field(f_hfluxt,field_u,type_real,llm)   ! mass "fluxes" accumulated in time
68    CALL allocate_field(f_wflux,field_t,type_real,llm+1)  ! vertical mass fluxes
69    CALL allocate_field(f_dmass,field_t,type_real,llm, name='dmass')
70
71    IF(caldyn_eta == eta_mass) THEN ! eta = mass coordinate (default)
72       CALL allocate_field(f_dps,field_t,type_real,name='dps')
73       CALL allocate_field(f_psm1,field_t,type_real,name='psm1')
74       CALL allocate_field(f_wfluxt,field_t,type_real,llm+1,name='wfluxt')
75       ! the following are unused but must point to something
76!       f_massm1 => f_mass
77    ELSE ! eta = Lagrangian vertical coordinate
78       CALL allocate_field(f_massm1,field_t,type_real,llm, name='massm1')
79       ! the following are unused but must point to something
80       f_wfluxt => f_wflux
81       f_dps  => f_phis
82       f_psm1 => f_phis
83    END IF
84
85    def='runge_kutta'
86    CALL getin('scheme',def)
87
88    SELECT CASE (TRIM(def))
89      CASE('euler')
90        scheme=euler
91        nb_stage=1
92      CASE ('runge_kutta')
93        scheme=rk4
94        nb_stage=4
95      CASE ('leapfrog_matsuno')
96        scheme=mlf
97        matsuno_period=5
98        CALL getin('matsuno_period',matsuno_period)
99        nb_stage=matsuno_period+1
100     ! Model state 2 time steps ago (MLF)
101        CALL allocate_field(f_theta_rhodzm2,field_t,type_real,llm)
102        CALL allocate_field(f_um2,field_u,type_real,llm)
103        IF(caldyn_eta == eta_mass) THEN ! eta = mass coordinate (default)
104           CALL allocate_field(f_psm2,field_t,type_real)
105           ! the following are unused but must point to something
106           f_massm2 => f_mass
107        ELSE ! eta = Lagrangian vertical coordinate
108           CALL allocate_field(f_massm2,field_t,type_real,llm)
109           ! the following are unused but must point to something
110           f_psm2 => f_phis
111        END IF
112
113    CASE default
114       PRINT*,'Bad selector for variable scheme : <', TRIM(def),             &
115            ' > options are <euler>, <runge_kutta>, <leapfrog_matsuno>'
116       STOP
117    END SELECT
118
119
120    CALL init_dissip
121    CALL init_caldyn
122    CALL init_guided
123    CALL init_advect_tracer
124    CALL init_check_conserve
125
126    CALL etat0(f_ps,f_mass,f_phis,f_theta_rhodz,f_u, f_q)
127
128    CALL transfert_request(f_phis,req_i0) 
129    CALL transfert_request(f_phis,req_i1) 
130    CALL writefield("phis",f_phis,once=.TRUE.)
131
132    CALL init_message(f_ps,req_i0,req_ps0)
133    CALL init_message(f_mass,req_i0,req_mass0)
134    CALL init_message(f_theta_rhodz,req_i0,req_theta_rhodz0)
135    CALL init_message(f_u,req_e0_vect,req_u0)
136    CALL init_message(f_q,req_i0,req_q0)
137
138  END SUBROUTINE init_timeloop
139 
140  SUBROUTINE timeloop
141  USE icosa
142  USE dissip_gcm_mod
143  USE disvert_mod
144  USE caldyn_mod
145  USE caldyn_gcm_mod, ONLY : req_ps, req_mass
146  USE etat0_mod
147  USE guided_mod
148  USE advect_tracer_mod
149  USE physics_mod
150  USE mpipara
151  USE omp_para
152  USE trace
153  USE transfert_mod
154  USE check_conserve_mod
155  USE xios_mod
156  USE output_field_mod
157  IMPLICIT NONE 
158    REAL(rstd),POINTER :: q(:,:,:)
159    REAL(rstd),POINTER :: phis(:), ps(:) ,psm1(:), psm2(:), dps(:)
160    REAL(rstd),POINTER :: u(:,:) , um1(:,:), um2(:,:), du(:,:)
161    REAL(rstd),POINTER :: rhodz(:,:), mass(:,:), massm1(:,:), massm2(:,:), dmass(:,:)
162    REAL(rstd),POINTER :: theta_rhodz(:,:) , theta_rhodzm1(:,:), theta_rhodzm2(:,:), dtheta_rhodz(:,:)
163    REAL(rstd),POINTER :: hflux(:,:),wflux(:,:),hfluxt(:,:),wfluxt(:,:)
164
165    INTEGER :: ind
166    INTEGER :: it,i,j,n,  stage
167    LOGICAL :: fluxt_zero(ndomain) ! set to .TRUE. to start accumulating fluxes in time
168    LOGICAL, PARAMETER :: check=.FALSE.
169    INTEGER :: start_clock
170    INTEGER :: stop_clock
171    INTEGER :: rate_clock
172   
173    CALL caldyn_BC(f_phis, f_wflux) ! set constant values in first/last interfaces
174
175!!$OMP BARRIER
176  DO ind=1,ndomain
177     IF (.NOT. assigned_domain(ind)) CYCLE
178     CALL swap_dimensions(ind)
179     CALL swap_geometry(ind)
180     rhodz=f_rhodz(ind); mass=f_mass(ind); ps=f_ps(ind)
181     IF(caldyn_eta==eta_mass) THEN
182        CALL compute_rhodz(.TRUE., ps, rhodz) ! save rhodz for transport scheme before dynamics update ps
183     ELSE
184        rhodz(:,:)=mass(:,:)
185     END IF
186  END DO
187  fluxt_zero=.TRUE.
188
189!$OMP MASTER
190  CALL SYSTEM_CLOCK(start_clock)
191!$OMP END MASTER   
192
193  CALL trace_on
194 
195  DO it=0,itaumax
196   
197    IF (xios_output) CALL xios_update_calendar(it)
198    IF (MOD(it,itau_sync)==0) THEN
199      CALL send_message(f_ps,req_ps0)
200      CALL wait_message(req_ps0)
201      CALL send_message(f_mass,req_mass0)
202      CALL wait_message(req_mass0)
203      CALL send_message(f_theta_rhodz,req_theta_rhodz0) 
204      CALL wait_message(req_theta_rhodz0) 
205      CALL send_message(f_u,req_u0)
206      CALL wait_message(req_u0)
207      CALL send_message(f_q,req_q0) 
208      CALL wait_message(req_q0) 
209
210!      CALL wait_message(req_ps0)
211!      CALL wait_message(req_mass0)
212!      CALL wait_message(req_theta_rhodz0)
213!      CALL wait_message(req_u0)
214!      CALL wait_message(req_q0)
215    ENDIF
216
217!$OMP MASTER   
218    IF (is_mpi_root) PRINT *,"It No :",It,"   t :",dt*It
219!$OMP END MASTER   
220    IF (mod(it,itau_out)==0 ) THEN
221      CALL update_time_counter(dt*it)
222      CALL output_field("q",f_q)
223      CALL check_conserve(f_ps,f_dps,f_u,f_theta_rhodz,f_phis,it) 
224    ENDIF
225   
226    CALL guided(it*dt,f_ps,f_theta_rhodz,f_u,f_q)
227
228    DO stage=1,nb_stage
229       CALL caldyn((stage==1) .AND. (MOD(it,itau_out)==0), &
230            f_phis,f_ps,f_mass,f_theta_rhodz,f_u, f_q, &
231            f_hflux, f_wflux, f_dps, f_dmass, f_dtheta_rhodz, f_du)
232       SELECT CASE (scheme)
233       CASE(euler)
234          CALL euler_scheme(.TRUE.)
235       CASE (rk4)
236          CALL rk_scheme(stage)
237       CASE (mlf)
238          CALL  leapfrog_matsuno_scheme(stage)
239       CASE DEFAULT
240          STOP
241       END SELECT
242    END DO
243
244    IF (MOD(it+1,itau_dissip)==0) THEN
245!         CALL send_message(f_ps,req_ps)
246!         CALL wait_message(req_ps) 
247       
248       IF(caldyn_eta==eta_mass) THEN
249          DO ind=1,ndomain
250             IF (.NOT. assigned_domain(ind)) CYCLE
251             CALL swap_dimensions(ind)
252             CALL swap_geometry(ind)
253             mass=f_mass(ind); ps=f_ps(ind);
254             CALL compute_rhodz(.TRUE., ps, mass)
255          END DO
256       ENDIF
257!       CALL send_message(f_mass,req_mass)
258!       CALL wait_message(req_mass) 
259       CALL dissip(f_u,f_du,f_mass,f_phis, f_theta_rhodz,f_dtheta_rhodz)
260!       CALL send_message(f_mass,req_mass)
261!       CALL wait_message(req_mass) 
262       CALL euler_scheme(.FALSE.)  ! update only u, theta
263    END IF
264
265    IF(MOD(it+1,itau_adv)==0) THEN
266
267       CALL advect_tracer(f_hfluxt,f_wfluxt,f_u, f_q,f_rhodz)  ! update q and rhodz after RK step
268       fluxt_zero=.TRUE.
269
270       ! FIXME : check that rhodz is consistent with ps
271       IF (check) THEN
272         DO ind=1,ndomain
273            IF (.NOT. assigned_domain(ind)) CYCLE
274            CALL swap_dimensions(ind)
275            CALL swap_geometry(ind)
276            rhodz=f_rhodz(ind); ps=f_ps(ind);
277            CALL compute_rhodz(.FALSE., ps, rhodz)   
278         END DO
279       ENDIF
280
281    END IF
282
283
284    IF (MOD(it+1,itau_physics)==0) THEN
285      CALL physics(it,f_phis, f_ps, f_theta_rhodz, f_u, f_wflux, f_q)
286    ENDIF
287   
288  ENDDO
289     
290  CALL check_conserve(f_ps,f_dps,f_u,f_theta_rhodz,f_phis,it) 
291
292!$OMP MASTER
293  CALL SYSTEM_CLOCK(stop_clock)
294  CALL SYSTEM_CLOCK(count_rate=rate_clock)
295   
296  IF (mpi_rank==0) THEN
297    PRINT *,"Time elapsed : ",(stop_clock-start_clock)*1./rate_clock
298  ENDIF 
299!$OMP END MASTER
300 
301 CONTAINS
302
303    SUBROUTINE Euler_scheme(with_dps)
304    IMPLICIT NONE
305    LOGICAL :: with_dps
306    INTEGER :: ind
307    INTEGER :: i,j,ij,l
308    CALL trace_start("Euler_scheme") 
309
310    DO ind=1,ndomain
311       IF (.NOT. assigned_domain(ind)) CYCLE
312       CALL swap_dimensions(ind)
313       CALL swap_geometry(ind)
314
315       IF(with_dps) THEN ! update ps/mass
316          IF(caldyn_eta==eta_mass) THEN ! update ps
317             ps=f_ps(ind) ; dps=f_dps(ind) ;             
318             IF (omp_first) THEN
319!$SIMD
320                DO ij=ij_begin,ij_end
321                    ps(ij)=ps(ij)+dt*dps(ij)
322                ENDDO
323             ENDIF
324          ELSE ! update mass
325             mass=f_mass(ind) ; dmass=f_dmass(ind) ;             
326             DO l=1,llm
327!$SIMD
328                DO ij=ij_begin,ij_end
329                    mass(ij,l)=mass(ij,l)+dt*dmass(ij,l)
330                ENDDO
331             END DO
332          END IF
333
334          hflux=f_hflux(ind);     hfluxt=f_hfluxt(ind)
335          wflux=f_wflux(ind);     wfluxt=f_wfluxt(ind)
336          CALL accumulate_fluxes(hflux,wflux,hfluxt,wfluxt,dt,fluxt_zero(ind))
337       END IF ! update ps/mass
338       
339       u=f_u(ind) ; theta_rhodz=f_theta_rhodz(ind)
340       du=f_du(ind) ; dtheta_rhodz=f_dtheta_rhodz(ind)
341
342       DO l=ll_begin,ll_end
343!$SIMD
344         DO ij=ij_begin,ij_end
345             u(ij+u_right,l)=u(ij+u_right,l)+dt*du(ij+u_right,l)
346             u(ij+u_lup,l)=u(ij+u_lup,l)+dt*du(ij+u_lup,l)
347             u(ij+u_ldown,l)=u(ij+u_ldown,l)+dt*du(ij+u_ldown,l)
348             theta_rhodz(ij,l)=theta_rhodz(ij,l)+dt*dtheta_rhodz(ij,l)
349         ENDDO
350       ENDDO
351    ENDDO
352
353    CALL trace_end("Euler_scheme") 
354
355    END SUBROUTINE Euler_scheme
356
357    SUBROUTINE RK_scheme(stage)
358      IMPLICIT NONE
359      INTEGER :: ind, stage
360      REAL(rstd), DIMENSION(4), PARAMETER :: coef = (/ .25, 1./3., .5, 1. /)
361      REAL(rstd) :: tau
362      INTEGER :: i,j,ij,l
363 
364      CALL trace_start("RK_scheme") 
365
366      tau = dt*coef(stage)
367
368      ! if mass coordinate, deal with ps first on one core
369      IF(caldyn_eta==eta_mass) THEN
370         IF (omp_first) THEN
371
372            DO ind=1,ndomain
373               IF (.NOT. assigned_domain(ind)) CYCLE
374               CALL swap_dimensions(ind)
375               CALL swap_geometry(ind)
376               ps=f_ps(ind) ; psm1=f_psm1(ind) ; dps=f_dps(ind) 
377               
378               IF (stage==1) THEN ! first stage : save model state in XXm1
379!$SIMD
380                 DO ij=ij_begin,ij_end
381                   psm1(ij)=ps(ij)
382                 ENDDO
383               ENDIF
384           
385               ! updates are of the form x1 := x0 + tau*f(x1)
386!$SIMD
387               DO ij=ij_begin,ij_end
388                   ps(ij)=psm1(ij)+tau*dps(ij)
389               ENDDO
390            ENDDO
391         ENDIF
392!         CALL send_message(f_ps,req_ps)
393!ym no overlap for now         
394!         CALL wait_message(req_ps) 
395     
396      ELSE ! Lagrangian coordinate, deal with mass
397         DO ind=1,ndomain
398            IF (.NOT. assigned_domain(ind)) CYCLE
399            CALL swap_dimensions(ind)
400            CALL swap_geometry(ind)
401            mass=f_mass(ind); dmass=f_dmass(ind); massm1=f_massm1(ind)
402
403            IF (stage==1) THEN ! first stage : save model state in XXm1
404               DO l=ll_begin,ll_end
405!$SIMD
406                 DO ij=ij_begin,ij_end
407                    massm1(ij,l)=mass(ij,l)
408                 ENDDO
409               ENDDO
410            END IF
411
412            ! updates are of the form x1 := x0 + tau*f(x1)
413            DO l=ll_begin,ll_end
414!$SIMD
415               DO ij=ij_begin,ij_end
416                   mass(ij,l)=massm1(ij,l)+tau*dmass(ij,l)
417               ENDDO
418            ENDDO
419         END DO
420!         CALL send_message(f_mass,req_mass)
421!ym no overlap for now         
422!         CALL wait_message(req_mass) 
423
424      END IF
425
426      ! now deal with other prognostic variables
427      DO ind=1,ndomain
428         IF (.NOT. assigned_domain(ind)) CYCLE
429         CALL swap_dimensions(ind)
430         CALL swap_geometry(ind)
431         u=f_u(ind)      ; du=f_du(ind)      ; um1=f_um1(ind) 
432         theta_rhodz=f_theta_rhodz(ind)
433         theta_rhodzm1=f_theta_rhodzm1(ind)
434         dtheta_rhodz=f_dtheta_rhodz(ind)
435         
436         IF (stage==1) THEN ! first stage : save model state in XXm1
437           DO l=ll_begin,ll_end
438!$SIMD
439                DO ij=ij_begin,ij_end
440                 um1(ij+u_right,l)=u(ij+u_right,l)
441                 um1(ij+u_lup,l)=u(ij+u_lup,l)
442                 um1(ij+u_ldown,l)=u(ij+u_ldown,l)
443                 theta_rhodzm1(ij,l)=theta_rhodz(ij,l)
444             ENDDO
445           ENDDO
446         END IF       
447
448         DO l=ll_begin,ll_end
449!$SIMD
450           DO ij=ij_begin,ij_end
451               u(ij+u_right,l)=um1(ij+u_right,l)+tau*du(ij+u_right,l)
452               u(ij+u_lup,l)=um1(ij+u_lup,l)+tau*du(ij+u_lup,l)
453               u(ij+u_ldown,l)=um1(ij+u_ldown,l)+tau*du(ij+u_ldown,l)
454               theta_rhodz(ij,l)=theta_rhodzm1(ij,l)+tau*dtheta_rhodz(ij,l)
455           ENDDO
456         ENDDO
457
458         IF(stage==nb_stage) THEN ! accumulate mass fluxes at last stage
459            hflux=f_hflux(ind);     hfluxt=f_hfluxt(ind)
460            wflux=f_wflux(ind);     wfluxt=f_wfluxt(ind)
461            CALL accumulate_fluxes(hflux,wflux, hfluxt,wfluxt, dt,fluxt_zero(ind))
462         END IF
463      END DO
464     
465      CALL trace_end("RK_scheme")
466     
467    END SUBROUTINE RK_scheme
468
469    SUBROUTINE leapfrog_matsuno_scheme(stage)
470    IMPLICIT NONE
471    INTEGER :: ind, stage
472    REAL :: tau
473
474      CALL trace_start("leapfrog_matsuno_scheme")
475   
476      tau = dt/nb_stage
477      DO ind=1,ndomain
478        IF (.NOT. assigned_domain(ind)) CYCLE
479        CALL swap_dimensions(ind)
480        CALL swap_geometry(ind)
481
482        ps=f_ps(ind)   ; u=f_u(ind)   ; theta_rhodz=f_theta_rhodz(ind)
483        psm1=f_psm1(ind) ; um1=f_um1(ind) ; theta_rhodzm1=f_theta_rhodzm1(ind)
484        psm2=f_psm2(ind) ; um2=f_um2(ind) ; theta_rhodzm2=f_theta_rhodzm2(ind)
485        dps=f_dps(ind) ; du=f_du(ind) ; dtheta_rhodz=f_dtheta_rhodz(ind)
486
487       
488        IF (stage==1) THEN
489          psm1(:)=ps(:) ; um1(:,:)=u(:,:) ; theta_rhodzm1(:,:)=theta_rhodz(:,:)
490          ps(:)=psm1(:)+tau*dps(:)
491          u(:,:)=um1(:,:)+tau*du(:,:)
492          theta_rhodz(:,:)=theta_rhodzm1(:,:)+tau*dtheta_rhodz(:,:)
493
494        ELSE IF (stage==2) THEN
495
496          ps(:)=psm1(:)+tau*dps(:)
497          u(:,:)=um1(:,:)+tau*du(:,:)
498          theta_rhodz(:,:)=theta_rhodzm1(:,:)+tau*dtheta_rhodz(:,:)
499
500          psm2(:)=psm1(:) ; theta_rhodzm2(:,:)=theta_rhodzm1(:,:) ; um2(:,:)=um1(:,:) 
501          psm1(:)=ps(:) ; theta_rhodzm1(:,:)=theta_rhodz(:,:) ; um1(:,:)=u(:,:) 
502
503        ELSE
504
505          ps(:)=psm2(:)+2*tau*dps(:)
506          u(:,:)=um2(:,:)+2*tau*du(:,:)
507          theta_rhodz(:,:)=theta_rhodzm2(:,:)+2*tau*dtheta_rhodz(:,:)
508
509          psm2(:)=psm1(:) ; theta_rhodzm2(:,:)=theta_rhodzm1(:,:) ; um2(:,:)=um1(:,:) 
510          psm1(:)=ps(:) ; theta_rhodzm1(:,:)=theta_rhodz(:,:) ; um1(:,:)=u(:,:) 
511
512        ENDIF
513     
514      ENDDO
515      CALL trace_end("leapfrog_matsuno_scheme")
516     
517    END SUBROUTINE leapfrog_matsuno_scheme 
518         
519  END SUBROUTINE timeloop   
520
521 SUBROUTINE accumulate_fluxes(hflux,wflux, hfluxt,wfluxt, tau,fluxt_zero)
522    USE icosa
523    USE omp_para
524    USE disvert_mod
525    IMPLICIT NONE
526    REAL(rstd), INTENT(IN)    :: hflux(3*iim*jjm,llm), wflux(iim*jjm,llm+1)
527    REAL(rstd), INTENT(INOUT) :: hfluxt(3*iim*jjm,llm), wfluxt(iim*jjm,llm+1)
528    REAL(rstd), INTENT(IN) :: tau
529    LOGICAL, INTENT(INOUT) :: fluxt_zero
530    INTEGER :: l,i,j,ij
531
532    IF(fluxt_zero) THEN
533
534       fluxt_zero=.FALSE.
535
536       DO l=ll_begin,ll_end
537!$SIMD
538         DO ij=ij_begin_ext,ij_end_ext
539             hfluxt(ij+u_right,l) = tau*hflux(ij+u_right,l)
540             hfluxt(ij+u_lup,l) = tau*hflux(ij+u_lup,l)
541             hfluxt(ij+u_ldown,l) = tau*hflux(ij+u_ldown,l)
542         ENDDO
543       ENDDO
544
545       IF(caldyn_eta==eta_mass) THEN ! no need for vertical fluxes if eta_lag
546          DO l=ll_begin,ll_endp1
547!$SIMD
548             DO ij=ij_begin,ij_end
549                wfluxt(ij,l) = tau*wflux(ij,l)
550             ENDDO
551          ENDDO
552       END IF
553
554    ELSE
555
556       DO l=ll_begin,ll_end
557!$SIMD
558         DO ij=ij_begin_ext,ij_end_ext
559             hfluxt(ij+u_right,l) = hfluxt(ij+u_right,l)+tau*hflux(ij+u_right,l)
560             hfluxt(ij+u_lup,l) = hfluxt(ij+u_lup,l)+tau*hflux(ij+u_lup,l)
561             hfluxt(ij+u_ldown,l) = hfluxt(ij+u_ldown,l)+tau*hflux(ij+u_ldown,l)
562         ENDDO
563       ENDDO
564
565       IF(caldyn_eta==eta_mass) THEN ! no need for vertical fluxes if eta_lag
566          DO l=ll_begin,ll_endp1
567!$SIMD
568             DO ij=ij_begin,ij_end
569                   wfluxt(ij,l) = wfluxt(ij,l)+tau*wflux(ij,l)
570             ENDDO
571          ENDDO
572       END IF
573
574   END IF
575
576  END SUBROUTINE accumulate_fluxes
577 
578!  FUNCTION maxval_i(p)
579!    USE icosa
580!    IMPLICIT NONE
581!    REAL(rstd), DIMENSION(iim*jjm) :: p
582!    REAL(rstd) :: maxval_i
583!    INTEGER :: j, ij
584!   
585!    maxval_i=p((jj_begin-1)*iim+ii_begin)
586!   
587!    DO j=jj_begin-1,jj_end+1
588!       ij=(j-1)*iim
589!       maxval_i = MAX(maxval_i, MAXVAL(p(ij+ii_begin:ij+ii_end)))
590!    END DO
591!  END FUNCTION maxval_i
592
593!  FUNCTION maxval_ik(p)
594!    USE icosa
595!    IMPLICIT NONE
596!    REAL(rstd) :: p(iim*jjm, llm)
597!    REAL(rstd) :: maxval_ik(llm)
598!    INTEGER :: l,j, ij
599!   
600!    DO l=1,llm
601!       maxval_ik(l)=p((jj_begin-1)*iim+ii_begin,l)
602!       DO j=jj_begin-1,jj_end+1
603!          ij=(j-1)*iim
604!          maxval_ik(l) = MAX(maxval_ik(l), MAXVAL(p(ij+ii_begin:ij+ii_end,l)))
605!       END DO
606!    END DO
607!  END FUNCTION maxval_ik
608
609END MODULE timeloop_gcm_mod
Note: See TracBrowser for help on using the repository browser.