source: codes/icosagcm/branches/SATURN_DYNAMICO/ICOSAGCM/src/sponge.f90 @ 314

Last change on this file since 314 was 309, checked in by millour, 10 years ago

Add third possibility for sponge layer, iflag_sponge=3, for a
sponge layer extending over the 'nb_sponge_layers' topmost layers.
EM

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