source: codes/icosagcm/trunk/src/etat0_ncar.f90 @ 25

Last change on this file since 25 was 25, checked in by dubos, 12 years ago

Minor changes :
caldyn_sw.f90, advect_tracer.f90
icosa_mod.f90 : added parameters for NCAR test cases needing global scope
guided_mod.f90 : CALL to guided_ncar now takes tt=it*dt instead of it as input

Significant changes :
timeloop_gcm.f90 : re-activated CALL to advection scheme
disvert_ncar.f90,
etat0_ncar.f90
guided_ncar_mod.f90 : simplification, introduced several getin(...), update due to recent changes in advection test cases (deformational flow, Hadley cell)
run_adv.def : new keys, reorganized for legibility

Tests :
icosa_gcm.exe tested with ncar_adv_shape=const and ncar_adv_wind=solid,deform,hadley.
q1=1 maintained to machine accuracy. Surface pressure slightly oscillates as expected.

FIXME : Tests by Sarvesh with revision 24 show incorrect advection of cosine bell by solid-body rotation. Not fixed.

File size: 6.9 KB
Line 
1MODULE etat0_ncar_mod
2  USE icosa
3  PRIVATE
4
5  REAL(rstd), PARAMETER :: h0=1.
6  REAL(rstd), PARAMETER :: lon0=3*pi/2
7  REAL(rstd), PARAMETER :: lat0=0.0
8  REAL(rstd), PARAMETER :: alpha=0.0
9  REAL(rstd), PARAMETER :: R0 = radius*0.5
10  REAL(rstd), PARAMETER :: lat1=0.
11  REAL(rstd), PARAMETER :: lat2=0.
12  REAL(rstd), PARAMETER :: lon1=pi/6
13  REAL(rstd), PARAMETER :: lon2=-pi/6
14  REAL(rstd), PARAMETER :: latc1=0.
15  REAL(rstd), PARAMETER :: latc2=0.
16  REAL(rstd), PARAMETER :: lonc1=5*pi/6
17  REAL(rstd), PARAMETER :: lonc2=7*pi/6
18  REAL(rstd), PARAMETER :: zt=1000.0
19  REAL(rstd), PARAMETER :: rt=radius*0.5
20  REAL(rstd), PARAMETER :: zc=5000.0
21
22  PUBLIC etat0
23 
24CONTAINS
25 
26  SUBROUTINE etat0(f_ps,f_phis,f_theta_rhodz,f_u,f_q)
27  USE icosa
28  IMPLICIT NONE
29    TYPE(t_field),POINTER :: f_ps(:)
30    TYPE(t_field),POINTER :: f_phis(:)
31    TYPE(t_field),POINTER :: f_theta_rhodz(:)
32    TYPE(t_field),POINTER :: f_u(:)
33    TYPE(t_field),POINTER :: f_q(:)
34 
35    REAL(rstd),POINTER :: ps(:)
36    REAL(rstd),POINTER :: phis(:)
37    REAL(rstd),POINTER :: theta_rhodz(:,:)
38    REAL(rstd),POINTER :: u(:,:)
39    REAL(rstd),POINTER :: q(:,:,:)
40    INTEGER :: ind
41   
42    DO ind=1,ndomain
43      CALL swap_dimensions(ind)
44      CALL swap_geometry(ind)
45      ps=f_ps(ind)
46      phis=f_phis(ind)
47      theta_rhodz=f_theta_rhodz(ind)
48      u=f_u(ind)
49      q=f_q(ind)
50      CALL compute_etat0_ncar(ps, phis, theta_rhodz, u, q(:,:,1))
51    ENDDO
52
53  END SUBROUTINE etat0
54 
55  SUBROUTINE compute_etat0_ncar(ps, phis, theta_rhodz, u, q)
56  USE icosa
57  USE disvert_mod
58  USE pression_mod
59  USE exner_mod
60  USE geopotential_mod
61  USE theta2theta_rhodz_mod
62  IMPLICIT NONE 
63  REAL(rstd),INTENT(OUT) :: ps(iim*jjm)
64  REAL(rstd),INTENT(OUT) :: phis(iim*jjm)
65  REAL(rstd),INTENT(OUT) :: theta_rhodz(iim*jjm,llm)
66  REAL(rstd),INTENT(OUT) :: u(3*iim*jjm,llm)
67  REAL(rstd),INTENT(OUT) :: q(iim*jjm,llm) 
68
69
70  REAL(rstd) :: qxt1(iim*jjm,llm)
71  REAL(rstd) :: lon, lat
72  REAL(rstd) ::dd1,dd2,dd1t1,dd1t2,dd2t1
73  REAL(rstd) :: pr, zr(llm+1), zrl(llm)
74  REAL(rstd) :: rr1,rr2,bb,cc,aa,hmx
75  REAL(rstd) :: X2(3),X1(3)
76  INTEGER :: i,j,n,l
77  CHARACTER(len=255) :: ncar_adv_shape
78
79  u = 0.0 ; phis = 0 ; theta_rhodz = 0 ; ps = ncar_p0
80 
81  DO l=1, llm+1
82     pr = ap(l) + bp(l)*ncar_p0
83     zr(l) = -kappa*cpp*ncar_T0/g*log(pr/ncar_p0) 
84  ENDDO
85 
86  DO l=1, llm 
87     zrl(l) = 0.5*(zr(l) + zr(l+1)) 
88  END DO
89 
90  ncar_adv_shape='cos_bell'
91  CALL getin('ncar_adv_shape',ncar_adv_shape)
92 
93  SELECT CASE(TRIM(ncar_adv_shape))
94     !--------------------------------------------- SINGLE COSINE BELL
95  CASE('const')
96     q=1
97  CASE('cos_bell')
98     CALL cosine_bell_1(q) 
99     
100  CASE('slotted_cyl')
101     CALL slotted_cylinders(q) 
102     
103  CASE('dbl_cos_bell_q1')
104     CALL cosine_bell_2(q) 
105     
106  CASE('dbl_cos_bell_q2')
107     CALL cosine_bell_2(q) 
108     DO l=1,llm
109        q(:,l)= 0.9 - 0.8*q(:,l)*q(:,l)
110     END DO
111     
112  CASE('complement')
113     ! tracer such that, in combination with the other tracer fields
114     ! with weight (3/10), the sum is equal to one
115     CALL cosine_bell_2(qxt1)
116     DO l = 1,llm
117        q(:,l) = 0.9 - 0.8*qxt1(:,l)*qxt1(:,l) 
118     END DO
119     q = q + qxt1 
120     CALL slotted_cylinders(qxt1)
121     q = q + qxt1 
122     q = 1. - q*0.3 
123     
124  CASE('hadley')  ! hadley like meridional circulation
125     CALL hadleyq(q) 
126     
127  CASE DEFAULT
128     PRINT *, 'Bad selector for variable ncar_adv_shape : <', TRIM(ncar_adv_shape),   &
129          '> options are <const>, <slotted_cyl>, <cos_bell>, <dbl_cos_bell_q1>', &
130          '<dbl_cos_bell_q2>, <complement>, <hadley>'
131     STOP
132     
133  END SELECT
134     
135CONTAINS
136
137!======================================================================
138
139    SUBROUTINE cosine_bell_1(hx)
140    IMPLICIT NONE
141    REAL(rstd) :: hx(iim*jjm,llm)
142   
143      DO l=1,llm 
144        DO j=jj_begin-1,jj_end+1
145          DO i=ii_begin-1,ii_end+1
146            n=(j-1)*iim+i
147            CALL xyz2lonlat(xyz_i(n,:),lon,lat)
148            CALL dist_lonlat(lon0,lat0,lon,lat,rr1)  ! GC distance from center
149            rr1 = radius*rr1
150            IF ( rr1 .LT. R0 ) then
151              hx(n,l)= 0.5*h0*(1+cos(pi*rr1/R0)) 
152            ELSE
153              hx(n,l)=0.0
154            END IF
155          END DO
156        END DO
157      END DO
158   
159    END SUBROUTINE cosine_bell_1
160
161!==============================================================================
162
163    SUBROUTINE   cosine_bell_2(hx) 
164    IMPLICIT NONE       
165    REAL(rstd) :: hx(iim*jjm,llm)
166   
167      DO l=1,llm
168        DO j=jj_begin-1,jj_end+1
169          DO i=ii_begin-1,ii_end+1
170            n=(j-1)*iim+i
171            CALL xyz2lonlat(xyz_i(n,:),lon,lat)
172            CALL dist_lonlat(lonc1,latc1,lon,lat,rr1)  ! GC distance from center
173            rr1 = radius*rr1
174            CALL dist_lonlat(lonc2,latc2,lon,lat,rr2)  ! GC distance from center
175            rr2 = radius*rr2
176            dd1t1 = rr1/rt
177            dd1t1 = dd1t1*dd1t1
178            dd1t2 = (zrl(l) - zc)/zt
179            dd1t2 = dd1t2*dd1t2 
180            dd1 = dd1t1 + dd1t2 
181            dd1 = Min(1.0,dd1) 
182            dd2t1 = rr2/rt
183            dd2t1 = dd2t1*dd2t1
184            dd2 = dd2t1 + dd1t2 
185            dd2 = Min(1.0,dd2) 
186            hx(n,l)= 0.5*(1. + cos(pi*dd1))+0.5*(1.+cos(pi*dd2))
187          END DO
188        END DO
189      END DO
190
191    END SUBROUTINE cosine_bell_2
192
193!=============================================================================
194
195    SUBROUTINE slotted_cylinders(hx) 
196    IMPLICIT NONE
197    REAL(rstd) :: hx(iim*jjm,llm)
198   
199      DO l=1,llm
200        DO j=jj_begin-1,jj_end+1
201          DO i=ii_begin-1,ii_end+1
202            n=(j-1)*iim+i
203            CALL xyz2lonlat(xyz_i(n,:),lon,lat)
204            CALL dist_lonlat(lonc1,latc1,lon,lat,rr1)  ! GC distance from center
205            rr1 = radius*rr1
206            CALL dist_lonlat(lonc2,latc2,lon,lat,rr2)  ! GC distance from center
207            rr2 = radius*rr2
208            dd1t1 = rr1/rt
209            dd1t1 = dd1t1*dd1t1
210            dd1t2 = (zrl(l) - zc)/zt
211            dd1t2 = dd1t2*dd1t2 
212            dd1 = dd1t1 + dd1t2 
213            dd2t1 = rr2/rt
214            dd2t1 = dd2t1*dd2t1
215            dd2 = dd2t1 + dd1t2
216           
217            IF ( dd1 .LT. 0.5 ) Then
218              hx(n,l) = 1.0
219            ELSEIF ( dd2 .LT. 0.5 ) Then
220              hx(n,l) = 1.0
221            ELSE
222              hx(n,l) = 0.1 
223            END IF 
224   
225            IF ( zrl(l) .GT. zc ) Then
226              IF ( ABS(latc1 - lat) .LT. 0.125 ) Then
227                hx(n,l)= 0.0
228              ENDIF
229            ENDIF 
230 
231          ENDDO
232       END DO
233      END DO
234
235    END SUBROUTINE slotted_cylinders 
236
237!==============================================================================
238
239    SUBROUTINE hadleyq(hx) 
240    IMPLICIT NONE
241    REAL(rstd)::hx(iim*jjm,llm) 
242    REAL(rstd),PARAMETER:: zz1=3500.,zz2=6500.,zz0=0.5*(zz1+zz2)
243   
244      DO l=1,llm
245        IF ( ( zz1 .LT. zrl(l) ) .and. ( zrl(l) .LT. zz2 ) )  THEN
246          hx(:,l) = 0.5*(1. + cos(0.002*pi*(zrl(l)-zz0)/3.)) 
247        ELSE
248          hx(:,l) = 0.0 
249        END IF
250      END DO
251    END SUBROUTINE hadleyq 
252
253  END SUBROUTINE compute_etat0_ncar
254 
255
256END MODULE etat0_ncar_mod
Note: See TracBrowser for help on using the repository browser.