source: codes/icosagcm/trunk/src/dissip/sponge.f90 @ 1047

Last change on this file since 1047 was 1047, checked in by ymipsl, 4 years ago

GPU port of sponge layer

YM

File size: 4.2 KB
Line 
1MODULE sponge_mod
2  USE icosa
3
4  PRIVATE
5 
6  REAL,SAVE :: tau_sponge !inverse of charactericstic relaxation time scale at the topmost layer (Hz)
7  INTEGER,SAVE :: iflag_sponge !0 --> for no sponge
8                               !1 --> for sponge over 4 topmost layers
9                               !2 --> for sponge from top to ~1% of top layer pressure
10  INTEGER,SAVE :: mode_sponge !1 --> u and v relax towards 0
11                              !2 --> u and v relax towards their zonal mean
12                              !3 --> u,v and pot. temp. relax towards their zonal mean
13!$OMP THREADPRIVATE(tau_sponge,iflag_sponge,mode_sponge)
14  REAL,ALLOCATABLE,SAVE :: rdamp(:) ! quenching coefficient
15  REAL,ALLOCATABLE,SAVE:: lambda(:) ! inverse or quenching time scale (Hz)
16
17  PUBLIC sponge, init_sponge, iflag_sponge
18
19CONTAINS
20
21  SUBROUTINE init_sponge
22  USE icosa
23  USE disvert_mod
24  USE omp_para
25  USE mpipara, ONLY: is_mpi_master
26  USE abort_mod
27  IMPLICIT NONE
28    INTEGER :: l
29
30    tau_sponge = 1.e-4
31    CALL getin("tau_sponge",tau_sponge)
32    PRINT*,'tau_sponge = ',tau_sponge
33
34    iflag_sponge = 0
35    CALL getin("iflag_sponge",iflag_sponge)
36    PRINT*,'iflag_sponge = ',iflag_sponge
37   
38    mode_sponge = 1
39    CALL getin("mode_sponge",mode_sponge)
40    PRINT*,'mode_sponge = ',mode_sponge
41
42    IF (iflag_sponge == 0) THEN
43      PRINT*,'init_sponge: no sponge'
44      RETURN
45    ENDIF
46
47
48!$OMP MASTER
49    ALLOCATE(rdamp(llm))
50    ALLOCATE(lambda(llm))
51    !$acc enter data create(rdamp(:),lambda(:)) async
52   
53    IF (iflag_sponge == 1) THEN
54! sponge quenching over the topmost 4 atmospheric layers
55        lambda(:)=0.
56        lambda(llm)=tau_sponge
57        lambda(llm-1)=tau_sponge/2.
58        lambda(llm-2)=tau_sponge/4.
59        lambda(llm-3)=tau_sponge/8.
60    ELSE IF (iflag_sponge == 2) THEN
61! sponge quenching over topmost layers down to pressures which are
62! higher than 100 times the topmost layer pressure
63        lambda(:)=tau_sponge*max(presnivs(llm)/presnivs(:)-0.01,0.)
64    ELSE
65      PRINT*,'Bad selector for variable iflag_sponge : <',iflag_sponge,             &
66            '> options are 0,1,2'
67      STOP
68    ENDIF
69
70! quenching coefficient rdamp(:)
71!         rdamp(:)=dt*lambda(:) ! Explicit Euler approx.
72!      rdamp(:)=1.-exp(-lambda(:)*dt)
73    rdamp(:)=itau_dissip*lambda(:)
74
75
76    IF (is_mpi_master) THEN
77      PRINT*,'lambda = '
78      DO l=ll_begin,ll_end
79        PRINT*,l,lambda(l)
80      ENDDO
81      PRINT*,'rdamp = '
82      DO l=ll_begin,ll_end
83        PRINT*,l,rdamp(l)
84      ENDDO
85    ENDIF
86!$OMP END MASTER
87!$OMP BARRIER
88    !$acc update device(rdamp(:), lambda(:)) async
89   
90  END SUBROUTINE init_sponge
91
92  SUBROUTINE sponge(f_ue,f_due,f_theta_rhodz,f_dtheta_rhodz)
93  USE icosa
94  USE theta2theta_rhodz_mod
95  USE pression_mod
96  USE exner_mod
97  USE geopotential_mod
98  USE trace
99  USE time_mod
100  USE omp_para
101  IMPLICIT NONE
102    TYPE(t_field),POINTER :: f_ue(:)
103    TYPE(t_field),POINTER :: f_due(:)
104    TYPE(t_field),POINTER :: f_theta_rhodz(:)
105    TYPE(t_field),POINTER :: f_dtheta_rhodz(:)
106
107    REAL(rstd),POINTER         :: due(:,:)!,due_sponge(:,:)
108    REAL(rstd),POINTER         :: ue(:,:)
109    REAL(rstd),POINTER         :: theta_rhodz(:,:,:)
110    REAL(rstd),POINTER         :: dtheta_rhodz(:,:,:)!,dtheta_sponge(:,:)
111
112    INTEGER :: ind
113    INTEGER :: l,ij
114
115!$OMP BARRIER
116   
117    CALL trace_start("sponge")
118
119    IF (mode_sponge == 1) THEN
120      DO ind=1,ndomain
121        IF (.NOT. assigned_domain(ind)) CYCLE
122        CALL swap_dimensions(ind)
123        CALL swap_geometry(ind)
124        ue=f_ue(ind) 
125        due=f_due(ind) 
126        theta_rhodz=f_theta_rhodz(ind)
127        dtheta_rhodz=f_dtheta_rhodz(ind)
128
129       !$acc parallel loop collapse(2) present(ue(:,:), due(:,:), rdamp(:), dtheta_rhodz)  async
130        DO l=ll_begin,ll_end
131!$SIMD
132          DO ij=ij_begin,ij_end
133
134            due(ij+u_right,l) = -rdamp(l)*ue(ij+u_right,l)
135            due(ij+u_lup,l)   = -rdamp(l)*ue(ij+u_lup,l)
136            due(ij+u_ldown,l) = -rdamp(l)*ue(ij+u_ldown,l)
137
138            dtheta_rhodz(ij,l,:) = 0.0
139          ENDDO
140        ENDDO
141       !$acc end parallel loop
142      END DO
143    ELSE
144      PRINT*,'Bad selector for variable mode_sponge : <',mode_sponge,             &
145            '> options 2 and 3 not available for the moment!'
146      STOP
147    ENDIF
148
149   CALL trace_end("sponge")
150
151!$OMP BARRIER
152  END SUBROUTINE sponge
153
154END MODULE sponge_mod
Note: See TracBrowser for help on using the repository browser.