source: codes/icosagcm/devel/src/vertical/disvert.f90

Last change on this file was 906, checked in by dubos, 5 years ago

devel : compute_rhodz for unstructured mesh

File size: 7.6 KB
Line 
1MODULE disvert_mod
2  USE icosa
3  REAL(rstd), SAVE, POINTER :: ap(:)
4!$OMP THREADPRIVATE(ap)
5  REAL(rstd), SAVE, POINTER :: bp(:)
6!$OMP THREADPRIVATE(bp)
7  REAL(rstd), SAVE, POINTER :: presnivs(:)
8!$OMP THREADPRIVATE(presnivs)
9  REAL(rstd), SAVE, POINTER :: mass_al(:), mass_bl(:), mass_ak(:), mass_bk(:), mass_dak(:), mass_dbk(:)
10!$OMP THREADPRIVATE(mass_al, mass_bl, mass_ak, mass_bk, mass_dak, mass_dbk)
11
12  REAL(rstd) :: ptop ! pressure at top of atmosphere l=llm+1
13!$OMP THREADPRIVATE(ptop)
14  ! vertical coordinate : Lagrangian or mass-based
15  INTEGER, SAVE :: caldyn_eta
16!$OMP THREADPRIVATE(caldyn_eta)
17  INTEGER, PARAMETER :: eta_mass=1, eta_lag=2
18  LOGICAL,SAVE :: ap_bp_present
19!$OMP THREADPRIVATE(ap_bp_present)
20
21CONTAINS
22
23  SUBROUTINE init_disvert
24  USE disvert_std_mod, ONLY: ap_std=>ap, bp_std=>bp, presnivs_std=>presnivs, init_disvert_std=>init_disvert
25  USE disvert_strato_mod, ONLY: ap_strato=>ap, bp_strato=>bp, presnivs_strato=>presnivs, init_disvert_strato=>init_disvert, init_disvert_strato_custom
26  USE disvert_apbp_mod, ONLY: ap_apbp=>ap, bp_apbp=>bp, presnivs_apbp=>presnivs, init_disvert_apbp=>init_disvert
27  USE disvert_ncar_mod, ONLY: ap_ncar=>ap, bp_ncar=>bp, presnivs_ncar=>presnivs, init_disvert_ncar=>init_disvert
28  USE disvert_ncarl30_mod, ONLY: ap_ncarl30=>ap, bp_ncarl30=>bp, presnivs_ncarl30=>presnivs, init_disvert_ncarl30=>init_disvert
29  USE disvert_dcmip31_mod, ONLY: ap_dcmip31=>ap, bp_dcmip31=>bp, presnivs_dcmip31=>presnivs, init_disvert_dcmip31=>init_disvert
30  USE disvert_dcmip200_mod, ONLY: ap_dcmip200=>ap, bp_dcmip200=>bp, presnivs_dcmip200=>presnivs, init_disvert_dcmip200=>init_disvert
31  USE icosa
32  USE mpipara
33  IMPLICIT NONE
34    CHARACTER(len=255) :: def
35    INTEGER :: l
36
37    def='eta_mass'
38    CALL getin('caldyn_eta',def)
39    SELECT CASE(TRIM(def))
40    CASE('eta_mass')
41       caldyn_eta=eta_mass
42    CASE('eta_lag')
43       caldyn_eta=eta_lag
44    CASE DEFAULT
45       IF (is_mpi_root) PRINT *,'Bad selector for variable caldyn_eta : <', TRIM(def),'> options are <eta_mass>, <eta_lag>'
46       STOP
47    END SELECT
48    IF (is_mpi_root) PRINT *, 'caldyn_eta=',TRIM(def), caldyn_eta, eta_lag, eta_mass
49
50    def='std'
51    ap_bp_present=.TRUE.
52    CALL getin("disvert",def)
53
54    SELECT CASE (TRIM(def))
55      CASE('none')
56         IF(caldyn_eta/=eta_lag) THEN
57            IF(is_mpi_root) PRINT *,'disvert_type=none must be used with caldyn_eta=eta_lag'
58            STOP
59         END IF
60         ap_bp_present=.FALSE.
61      CASE('std')
62   
63        CALL init_disvert_std
64        ap=>ap_std
65        bp=>bp_std
66        presnivs=>presnivs_std
67     
68      CASE('strato')
69       
70        CALL init_disvert_strato
71        ap=>ap_strato
72        bp=>bp_strato
73        presnivs=>presnivs_strato
74
75      CASE('strato_custom')
76       
77        CALL init_disvert_strato_custom
78        ap=>ap_strato
79        bp=>bp_strato
80        presnivs=>presnivs_strato
81
82      CASE('read_apbp')
83   
84        CALL init_disvert_apbp
85        ap=>ap_apbp
86        bp=>bp_apbp
87        presnivs=>presnivs_apbp
88       
89      CASE ('ncar')
90
91        CALL init_disvert_ncar
92        ap=>ap_ncar
93        bp=>bp_ncar
94        presnivs=>presnivs_ncar
95
96      CASE ('dcmip31')
97
98        CALL init_disvert_dcmip31
99        ap=>ap_dcmip31
100        bp=>bp_dcmip31
101        presnivs=>presnivs_dcmip31
102
103      CASE ('dcmip200')
104
105        CALL init_disvert_dcmip200
106        ap=>ap_dcmip200
107        bp=>bp_dcmip200
108        presnivs=>presnivs_dcmip200
109
110      CASE ('ncarl30')
111
112        CALL init_disvert_ncarl30
113        ap=>ap_ncarl30
114        bp=>bp_ncarl30
115        presnivs=>presnivs_ncarl30
116      CASE default
117        IF (is_mpi_root) PRINT*,'Bad selector for variable disvert : <', TRIM(def),"> options are <std>, <ncar>, <ncarl30>" 
118        STOP
119       
120    END SELECT
121
122    IF(ap_bp_present) THEN
123       ! Convert from pressure coordinate to mass coordinate
124       ! pk = ap(k) + bp(k)*ps(ij) = ptop + g*( mass_ak(k) + mass_bk(k)*ms(ij) )
125       ptop = ap(llm+1)
126       ALLOCATE(mass_al(llm+1))
127       ALLOCATE(mass_bl(llm+1))
128       ALLOCATE(mass_ak(llm))
129       ALLOCATE(mass_bk(llm))
130       ALLOCATE(mass_dak(llm))
131       ALLOCATE(mass_dbk(llm))
132
133       ! FIXME : leave ps for the moment ; change ps to ms later
134       DO l=1,llm+1
135          !       mass_al(l) = (ap(l)-ptop)/g
136          !       mass_bl(l) = bp(l)/g
137          mass_al(l) = (ap(l)-ptop)
138          mass_bl(l) = bp(l)
139       END DO
140       DO l=1,llm
141          mass_ak(l) = .5*(mass_al(l)+mass_al(l+1))
142          mass_bk(l) = .5*(mass_bl(l)+mass_bl(l+1))
143          mass_dak(l) = mass_al(l)-mass_al(l+1)  ! >0
144          mass_dbk(l) = mass_bl(l)-mass_bl(l+1)  ! >0
145       END DO
146    END IF
147
148  END SUBROUTINE init_disvert 
149 
150  SUBROUTINE write_apbp
151  USE icosa
152  USE netcdf_mod
153  IMPLICIT NONE
154    REAL(rstd) :: val(llm)
155    INTEGER :: status
156    INTEGER :: lev,ilev
157    INTEGER :: ncid,levid,ilevid,hyaiid,hybiid,hyamid,hybmid,P0id
158    INTEGER :: l
159   
160    IF (no_io) RETURN
161   
162!$OMP BARRIER
163!$OMP MASTER   
164    status = NF90_CREATE('apbp.nc', NF90_CLOBBER, ncid)
165    status = NF90_DEF_DIM(ncid,'lev',llm,lev)
166    status = NF90_DEF_DIM(ncid,'ilev',llm+1,ilev)
167   
168    status = NF90_DEF_VAR(ncid,'lev',NF90_DOUBLE,(/ lev /),levid)
169    status = NF90_PUT_ATT(ncid,levid,"long_name","hybrid level at midpoints (1000*(A+B))")
170    status = NF90_PUT_ATT(ncid,levid,"units","Pa")
171    status = NF90_PUT_ATT(ncid,levid,"positive","up")
172    status = NF90_PUT_ATT(ncid,levid,"standard_name","atmosphere_hybrid_sigma_pressure_coordinate")
173    status = NF90_PUT_ATT(ncid,levid,"formula_terms","a: hyam b: hybm p0: P0 ps: PS")
174
175    status = NF90_DEF_VAR(ncid,'ilev',NF90_DOUBLE,(/ ilev /),ilevid)
176    status = NF90_PUT_ATT(ncid,ilevid,"long_name","hybrid level at interfaces (1000*(A+B))")
177    status = NF90_PUT_ATT(ncid,ilevid,"units","Pa")
178    status = NF90_PUT_ATT(ncid,ilevid,"positive","up")
179    status = NF90_PUT_ATT(ncid,ilevid,"standard_name","atmosphere_hybrid_sigma_pressure_coordinate")
180    status = NF90_PUT_ATT(ncid,ilevid,"formula_terms","a: hyai b: hybi p0: P0 ps: PS")
181   
182    status = NF90_DEF_VAR(ncid,'hyai',NF90_DOUBLE,(/ ilev /),hyaiid)
183    status = NF90_PUT_ATT(ncid,hyaiid,"long_name","hybrid A coefficient at layer interfaces")
184
185    status = NF90_DEF_VAR(ncid,'hybi',NF90_DOUBLE,(/ ilev /),hybiid)
186    status = NF90_PUT_ATT(ncid,hybiid,"long_name","hybrid B coefficient at layer interfaces")
187
188    status = NF90_DEF_VAR(ncid,'hyam',NF90_DOUBLE,(/ lev /),hyamid)
189    status = NF90_PUT_ATT(ncid,hyamid,"long_name","hybrid A coefficient at midpoint interfaces")
190
191    status = NF90_DEF_VAR(ncid,'hybm',NF90_DOUBLE,(/ lev /),hybmid)
192    status = NF90_PUT_ATT(ncid,hybmid,"long_name","hybrid B coefficient at midpoint interfaces")
193   
194    status = NF90_DEF_VAR(ncid,'P0',NF90_DOUBLE,varid=P0id)
195
196    status = NF90_ENDDEF(ncid)   
197
198    IF(ap_bp_present) THEN
199   
200    status=NF90_PUT_VAR(ncid,ilevid, ap(:)+bp(:)*Preff)
201   
202    DO l=1,llm
203      val(l)= 0.5*(ap(l+1)+ap(l)+Preff*(bp(l)+bp(l+1)))
204    ENDDO
205   
206    status=NF90_PUT_VAR(ncid,levid, val)
207
208    status=NF90_PUT_VAR(ncid,hyaiid, ap(:)/Preff)
209    status=NF90_PUT_VAR(ncid,hybiid, bp(:))
210   
211    DO l=1,llm
212      val(l)= 0.5*(ap(l+1)+ap(l))
213    ENDDO
214    status=NF90_PUT_VAR(ncid,hyamid, val(:)/Preff)
215   
216    DO l=1,llm
217      val(l)= 0.5*(bp(l+1)+bp(l))
218    ENDDO
219    status=NF90_PUT_VAR(ncid,hybmid, val(:))
220 
221    status=NF90_PUT_VAR(ncid,P0id, Preff)
222   
223    END IF
224
225    status=NF90_CLOSE(ncid)
226!$OMP END MASTER
227!$OMP BARRIER
228  END SUBROUTINE write_apbp
229
230END MODULE disvert_mod
Note: See TracBrowser for help on using the repository browser.