source: codes/icosagcm/devel/src/unstructured/caldyn_unstructured.F90

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

devel : DySL for enstrophy-conserving scheme

File size: 7.8 KB
Line 
1MODULE caldyn_unstructured_mod
2  USE ISO_C_BINDING
3  USE OMP_LIB
4  USE earth_const
5  USE data_unstructured_mod
6  IMPLICIT NONE
7  SAVE
8  PRIVATE
9
10  PUBLIC :: compute_NH_geopot, compute_caldyn_slow_NH, compute_caldyn_solver, &
11       compute_caldyn_vert_NH, compute_geopot, compute_caldyn_slow_hydro, &
12       caldyn_vert, compute_coriolis, compute_theta, compute_pvort_only, &
13       compute_caldyn_fast, gradient, div, &
14       compute_scalar_laplacian, compute_curl_laplacian
15
16CONTAINS
17
18#include "unstructured.h90"
19
20#define PHI_BOT(ij) Phi_bot
21
22!----------------------------- Non-Hydrostatic -----------------------------
23
24SUBROUTINE compute_NH_geopot(tau, m_ik, m_il, theta, W_il, Phi_il)
25  FIELD_MASS   :: m_ik, theta   ! IN*2
26  FIELD_GEOPOT :: m_il, W_il, Phi_il, Phi_star_il  ! IN,INOUT*2, LOCAL
27  NUM :: tau, gamma, tau2_g, tau2_g2, g2, gm2, vreff, Rd_preff
28  INTEGER :: iter
29  LOGICAL :: debug_hevi_solver
30  DECLARE_INDICES
31  NUM :: rho_ij, X_ij, Y_ij, wil, rho_c2_mik, c2_mik, ml_g2
32#define COLUMN 0
33#if COLUMN 
34  NUM1(llm)  :: pk, Ak, Ck
35  NUM1(llm+1):: Rl, Bl, Dl, xl
36#define p_ik(l,ij) pk(l)
37#define A_ik(l,ij) Ak(l)
38#define C_ik(l,ij) Ck(l)
39#define R_il(l,ij) Rl(l)
40#define B_il(l,ij) Bl(l)
41#define D_il(l,ij) Dl(l)
42#define x_il(l,ij) xl(l)
43#else
44  FIELD_MASS :: p_ik, A_ik, C_ik
45  FIELD_GEOPOT :: R_il, B_il, D_il, x_il
46#endif
47
48  debug_hevi_solver=.FALSE.
49!$OMP MASTER
50  debug_hevi_solver = debug_hevi_solver_
51!$OMP END MASTER
52
53  START_TRACE(id_NH_geopot, 7,0,0)
54#include "../kernels_unst/compute_NH_geopot.k90"
55  STOP_TRACE 
56
57!$OMP MASTER
58  debug_hevi_solver_ = debug_hevi_solver
59!$OMP END MASTER
60
61#if COLUMN
62#undef p_ik
63#undef A_ik
64#undef C_ik
65#undef R_il
66#undef B_il
67#undef D_il
68#undef x_il
69#endif
70#undef COLUMN
71END SUBROUTINE compute_NH_geopot
72
73SUBROUTINE compute_caldyn_slow_NH(u,rhodz,Phi,W, w_il,berni,gradPhi2,DePhil,v_el,G_el,F_el, hflux,du,dPhi,dW)
74  FIELD_U      :: u, hflux, du   ! IN, OUT, OUT
75  FIELD_MASS   :: rhodz, berni   ! IN, BUF
76  FIELD_GEOPOT :: Phi,W,dPhi,dW, w_il, gradPhi2  ! IN,IN, OUT,OUT, BUF*2
77  FIELD_UL     :: DePhil, v_el, G_el, F_el ! BUF*4
78  DECLARE_INDICES
79  DECLARE_EDGES
80  NUM :: W_el, W2_el, gPhi2, dP, divG, u2, uu
81  START_TRACE(id_slow_NH, 5,0,3)
82#include "../kernels_unst/caldyn_slow_NH.k90"
83  STOP_TRACE
84END SUBROUTINE compute_caldyn_slow_NH
85
86SUBROUTINE compute_caldyn_solver(tau,rhodz,theta, berni,pres,m_il, pk,geopot,W,dPhi,dW,du)
87  NUM, INTENT(IN) :: tau
88  FIELD_MASS   :: rhodz,pk,berni,pres    ! IN, OUT, BUF*2
89  FIELD_THETA  :: theta                  ! IN
90  FIELD_GEOPOT :: geopot,W,dPhi,dW, m_il ! INOUT,INOUT, OUT,OUT, BUF
91  FIELD_U      :: du                     ! OUT
92  DECLARE_INDICES
93  NUM :: X_ij, rho_ij, T_ij, gamma, Cvd, vreff, Rd_preff
94#include "../kernels_unst/caldyn_mil.k90"
95  IF(tau>0) THEN ! solve implicit problem for geopotential
96    CALL compute_NH_geopot(tau, rhodz, m_il, theta, W, geopot)
97  END IF
98  START_TRACE(id_solver, 7,0,1)
99#include "../kernels_unst/caldyn_solver.k90"
100  STOP_TRACE
101END SUBROUTINE compute_caldyn_solver
102
103SUBROUTINE compute_caldyn_vert_NH(mass,geopot,W,wflux, eta_dot,wcov,W_etadot, du,dPhi,dW)
104  FIELD_MASS   :: mass, eta_dot, wcov, W_etadot ! IN, BUF*3
105  FIELD_GEOPOT :: geopot,W,wflux,dPhi,dW ! IN*3, INOUT*2
106  FIELD_U      :: du ! INOUT
107  DECLARE_INDICES
108  NUM :: w_ij, wflux_ij
109  START_TRACE(id_vert_NH, 6,0,1)
110#include "../kernels_unst/caldyn_vert_NH.k90"
111  STOP_TRACE
112END SUBROUTINE compute_caldyn_vert_NH
113
114!----------------------------- Hydrostatic -------------------------------
115
116SUBROUTINE compute_geopot(rhodz,theta,ps,pk,geopot)
117  FIELD_MASS  :: rhodz,pk   ! IN, OUT
118  FIELD_THETA :: theta      ! IN
119  FIELD_GEOPOT :: geopot    ! IN(l=1)/OUT(l>1)
120  FIELD_PS     :: ps        ! OUT
121  DECLARE_INDICES
122  NUM :: gdz, ke, uu, chi, gv, exner_ik, temp_ik, p_ik, qv, Rmix, Cp_ik
123  START_TRACE(id_geopot, 3,0,3)
124#include "../kernels_unst/compute_geopot.k90"
125  STOP_TRACE
126END SUBROUTINE compute_geopot
127!
128SUBROUTINE compute_caldyn_slow_hydro(rhodz,theta,u, berni,hflux,du)
129  FIELD_MASS  :: rhodz,berni! IN
130  FIELD_THETA :: theta      ! IN
131  FIELD_U     :: u,hflux,du ! IN, OUT, OUT
132  DECLARE_INDICES
133  DECLARE_EDGES
134  LOGICAL, PARAMETER :: zero=.TRUE.
135  NUM :: ke, uu
136  START_TRACE(id_slow_hydro, 3,0,3)
137#include "../kernels_unst/caldyn_slow_hydro.k90"
138  STOP_TRACE
139END SUBROUTINE compute_caldyn_slow_hydro
140
141!---------------------------------- Generic ------------------------------
142
143SUBROUTINE caldyn_vert(convm,rhodz,theta,u, dmass_col,wflux,dtheta_rhodz,du, wwuu)
144  FIELD_PS    :: dmass_col
145  FIELD_MASS  :: convm, rhodz
146  FIELD_U     :: u,du
147  FIELD_THETA :: dtheta_rhodz, theta
148  FIELD_GEOPOT :: wflux
149  FIELD_UL     :: wwuu
150  DECLARE_INDICES
151  NUM :: dF_deta, dFu_deta
152  wwuu=0.
153  !$OMP BARRIER
154  START_TRACE(id_vert, 5,0,3)
155#include "../kernels_unst/caldyn_wflux.k90"
156#include "../kernels_unst/caldyn_dmass.k90"
157#include "../kernels_unst/caldyn_vert.k90"
158  STOP_TRACE
159END SUBROUTINE caldyn_vert
160
161SUBROUTINE compute_coriolis(hflux,theta,qu,Ftheta, convm,dtheta_rhodz,du)
162  FIELD_U     :: hflux, Ftheta, qu, du
163  FIELD_MASS  :: convm
164  FIELD_THETA :: theta, dtheta_rhodz
165  INTEGER, PARAMETER :: conserv_energy=1, conserv_enstrophy=2, caldyn_conserv = conserv_enstrophy ! FIXME
166  DECLARE_INDICES
167  DECLARE_EDGES
168  NUM :: divF, du_trisk
169  START_TRACE(id_coriolis, 3,4,0) ! primal, dual, edge
170#include "../kernels_unst/coriolis.k90"
171  STOP_TRACE
172END SUBROUTINE
173
174SUBROUTINE compute_theta(mass_col,rhodz,theta_rhodz, theta)
175  FIELD_PS :: mass_col
176  FIELD_MASS :: rhodz
177  FIELD_THETA :: theta, theta_rhodz
178  DECLARE_INDICES
179  NUM :: m
180  START_TRACE(id_theta, 3,0,0) ! primal, dual, edge
181#include "../kernels_unst/theta.k90"
182  STOP_TRACE
183END SUBROUTINE
184
185SUBROUTINE compute_pvort_only(rhodz,u,qv,qu)
186  FIELD_MASS :: rhodz
187  FIELD_U    :: u,qu
188  FIELD_Z    :: qv
189  DECLARE_INDICES
190  DECLARE_EDGES
191  DECLARE_VERTICES
192  NUM :: etav, hv
193  START_TRACE(id_pvort_only, 1,1,2) ! primal, dual, edge
194#include "../kernels_unst/pvort_only.k90"
195  STOP_TRACE
196END SUBROUTINE compute_pvort_only
197
198SUBROUTINE compute_caldyn_fast(tau, pk,berni,theta,geopot, du,u)
199  NUM, INTENT(IN) :: tau
200  FIELD_MASS   :: pk,berni  ! INOUT, OUT
201  FIELD_THETA  :: theta     ! IN
202  FIELD_GEOPOT :: geopot    ! IN
203  FIELD_U      :: u,du      ! INOUT,INOUT
204  DECLARE_INDICES
205  DECLARE_EDGES
206  NUM          :: due, cp_ik, Phi_ik
207  START_TRACE(id_fast, 4,0,2) ! primal, dual, edge
208#include "../kernels_unst/caldyn_fast.k90"
209  STOP_TRACE
210END SUBROUTINE compute_caldyn_fast
211
212!----------------------------- Unused -----------------------------
213
214#ifdef BEGIN_DYSL
215KERNEL(gradient)
216  FORALL_CELLS_EXT()
217    ON_EDGES
218      grad(EDGE) = SIGN*(b(CELL2)-b(CELL1))
219    END_BLOCK
220  END_BLOCK
221END_BLOCK
222
223KERNEL(div)
224  FORALL_CELLS_EXT()
225    ON_PRIMAL
226      div_ij=0.
227      FORALL_EDGES
228        div_ij = div_ij + SIGN*LE_DE*u(EDGE)
229      END_BLOCK
230      divu(CELL) = div_ij / AI
231    END_BLOCK
232  END_BLOCK
233END_BLOCK
234#endif END_DYSL
235
236SUBROUTINE gradient(b,grad) BINDC(gradient)
237  FIELD_MASS :: b
238  FIELD_U    :: grad
239  DECLARE_INDICES
240#include "../kernels_unst/gradient.k90"
241END SUBROUTINE
242!
243SUBROUTINE div(u,divu) BINDC(div)
244  FIELD_MASS :: divu
245  FIELD_U    :: u
246  DECLARE_INDICES
247  DECLARE_EDGES
248  NUM :: div_ij
249  !$OMP PARALLEL NUM_THREADS(nb_threads)
250#include "../kernels_unst/div.k90"
251  !$OMP END PARALLEL
252END SUBROUTINE
253
254SUBROUTINE compute_scalar_laplacian(b,grad,divu)
255  FIELD_MASS   :: b, divu ! IN, OUT
256  FIELD_U      :: grad ! BUF
257  DECLARE_INDICES
258  DECLARE_EDGES
259  NUM :: div_ij
260  START_TRACE(id_scalar_laplacian, 0,0,1)
261#include "../kernels_unst/scalar_laplacian.k90"
262  STOP_TRACE
263END SUBROUTINE compute_scalar_laplacian
264
265SUBROUTINE compute_curl_laplacian(u,qv,curlcurl)
266  FIELD_Z   :: qv ! BUF
267  FIELD_U   :: u, curlcurl ! IN,OUT
268  DECLARE_INDICES
269  DECLARE_EDGES
270  DECLARE_VERTICES
271  NUM :: etav
272  START_TRACE(id_scalar_laplacian, 0,0,1)
273#include "../kernels_unst/curl_laplacian.k90"
274  STOP_TRACE
275END SUBROUTINE compute_curl_laplacian
276
277END MODULE caldyn_unstructured_mod
Note: See TracBrowser for help on using the repository browser.