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

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

devel : DySL for enstrophy-conserving scheme

File size: 7.8 KB
RevLine 
[615]1MODULE caldyn_unstructured_mod
2  USE ISO_C_BINDING
3  USE OMP_LIB
[836]4  USE earth_const
[638]5  USE data_unstructured_mod
[615]6  IMPLICIT NONE
7  SAVE
[833]8  PRIVATE
[615]9
[833]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
[638]16CONTAINS
17
[688]18#include "unstructured.h90"
[650]19
[638]20#define PHI_BOT(ij) Phi_bot
21
22!----------------------------- Non-Hydrostatic -----------------------------
[615]23
[658]24SUBROUTINE compute_NH_geopot(tau, m_ik, m_il, theta, W_il, Phi_il)
25  FIELD_MASS   :: m_ik, theta   ! IN*2
[665]26  FIELD_GEOPOT :: m_il, W_il, Phi_il, Phi_star_il  ! IN,INOUT*2, LOCAL
[688]27  NUM :: tau, gamma, tau2_g, tau2_g2, g2, gm2, vreff, Rd_preff
[658]28  INTEGER :: iter
[749]29  LOGICAL :: debug_hevi_solver
[615]30  DECLARE_INDICES
[688]31  NUM :: rho_ij, X_ij, Y_ij, wil, rho_c2_mik, c2_mik, ml_g2
[658]32#define COLUMN 0
33#if COLUMN 
[688]34  NUM1(llm)  :: pk, Ak, Ck
35  NUM1(llm+1):: Rl, Bl, Dl, xl
[658]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
[749]48  debug_hevi_solver=.FALSE.
49!$OMP MASTER
50  debug_hevi_solver = debug_hevi_solver_
51!$OMP END MASTER
52
[658]53  START_TRACE(id_NH_geopot, 7,0,0)
[615]54#include "../kernels_unst/compute_NH_geopot.k90"
[658]55  STOP_TRACE 
56
[749]57!$OMP MASTER
58  debug_hevi_solver_ = debug_hevi_solver
59!$OMP END MASTER
60
[658]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
[615]71END SUBROUTINE compute_NH_geopot
[638]72
[665]73SUBROUTINE compute_caldyn_slow_NH(u,rhodz,Phi,W, w_il,berni,gradPhi2,DePhil,v_el,G_el,F_el, hflux,du,dPhi,dW)
[615]74  FIELD_U      :: u, hflux, du   ! IN, OUT, OUT
[665]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
[615]78  DECLARE_INDICES
[650]79  DECLARE_EDGES
[688]80  NUM :: W_el, W2_el, gPhi2, dP, divG, u2, uu
[658]81  START_TRACE(id_slow_NH, 5,0,3)
[615]82#include "../kernels_unst/caldyn_slow_NH.k90"
[658]83  STOP_TRACE
[615]84END SUBROUTINE compute_caldyn_slow_NH
[638]85
[665]86SUBROUTINE compute_caldyn_solver(tau,rhodz,theta, berni,pres,m_il, pk,geopot,W,dPhi,dW,du)
[688]87  NUM, INTENT(IN) :: tau
[665]88  FIELD_MASS   :: rhodz,pk,berni,pres    ! IN, OUT, BUF*2
[615]89  FIELD_THETA  :: theta                  ! IN
[665]90  FIELD_GEOPOT :: geopot,W,dPhi,dW, m_il ! INOUT,INOUT, OUT,OUT, BUF
[615]91  FIELD_U      :: du                     ! OUT
92  DECLARE_INDICES
[688]93  NUM :: X_ij, rho_ij, T_ij, gamma, Cvd, vreff, Rd_preff
[658]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)
[615]99#include "../kernels_unst/caldyn_solver.k90"
[658]100  STOP_TRACE
[615]101END SUBROUTINE compute_caldyn_solver
[638]102
[665]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
[615]107  DECLARE_INDICES
[688]108  NUM :: w_ij, wflux_ij
[658]109  START_TRACE(id_vert_NH, 6,0,1)
[615]110#include "../kernels_unst/caldyn_vert_NH.k90"
[658]111  STOP_TRACE
[615]112END SUBROUTINE compute_caldyn_vert_NH
[638]113
[615]114!----------------------------- Hydrostatic -------------------------------
[638]115
[615]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
[836]122  NUM :: gdz, ke, uu, chi, gv, exner_ik, temp_ik, p_ik, qv, Rmix, Cp_ik
[658]123  START_TRACE(id_geopot, 3,0,3)
[615]124#include "../kernels_unst/compute_geopot.k90"
[658]125  STOP_TRACE
[615]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
[650]133  DECLARE_EDGES
[615]134  LOGICAL, PARAMETER :: zero=.TRUE.
[688]135  NUM :: ke, uu
[658]136  START_TRACE(id_slow_hydro, 3,0,3)
[615]137#include "../kernels_unst/caldyn_slow_hydro.k90"
[658]138  STOP_TRACE
[615]139END SUBROUTINE compute_caldyn_slow_hydro
[638]140
[615]141!---------------------------------- Generic ------------------------------
[638]142
[615]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
[642]149  FIELD_UL     :: wwuu
[615]150  DECLARE_INDICES
[688]151  NUM :: dF_deta, dFu_deta
[615]152  wwuu=0.
[645]153  !$OMP BARRIER
[658]154  START_TRACE(id_vert, 5,0,3)
[624]155#include "../kernels_unst/caldyn_wflux.k90"
156#include "../kernels_unst/caldyn_dmass.k90"
[615]157#include "../kernels_unst/caldyn_vert.k90"
[658]158  STOP_TRACE
[615]159END SUBROUTINE caldyn_vert
[638]160
[645]161SUBROUTINE compute_coriolis(hflux,theta,qu,Ftheta, convm,dtheta_rhodz,du)
[615]162  FIELD_U     :: hflux, Ftheta, qu, du
163  FIELD_MASS  :: convm
164  FIELD_THETA :: theta, dtheta_rhodz
[940]165  INTEGER, PARAMETER :: conserv_energy=1, conserv_enstrophy=2, caldyn_conserv = conserv_enstrophy ! FIXME
[615]166  DECLARE_INDICES
[650]167  DECLARE_EDGES
[688]168  NUM :: divF, du_trisk
[658]169  START_TRACE(id_coriolis, 3,4,0) ! primal, dual, edge
[615]170#include "../kernels_unst/coriolis.k90"
[658]171  STOP_TRACE
[615]172END SUBROUTINE
[638]173
[615]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
[688]179  NUM :: m
[658]180  START_TRACE(id_theta, 3,0,0) ! primal, dual, edge
[615]181#include "../kernels_unst/theta.k90"
[658]182  STOP_TRACE
[615]183END SUBROUTINE
[638]184
[615]185SUBROUTINE compute_pvort_only(rhodz,u,qv,qu)
186  FIELD_MASS :: rhodz
187  FIELD_U    :: u,qu
188  FIELD_Z    :: qv
189  DECLARE_INDICES
[650]190  DECLARE_EDGES
191  DECLARE_VERTICES
[688]192  NUM :: etav, hv
[658]193  START_TRACE(id_pvort_only, 1,1,2) ! primal, dual, edge
[615]194#include "../kernels_unst/pvort_only.k90"
[658]195  STOP_TRACE
[615]196END SUBROUTINE compute_pvort_only
[638]197
[615]198SUBROUTINE compute_caldyn_fast(tau, pk,berni,theta,geopot, du,u)
[688]199  NUM, INTENT(IN) :: tau
[615]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
[650]205  DECLARE_EDGES
[935]206  NUM          :: due, cp_ik, Phi_ik
[658]207  START_TRACE(id_fast, 4,0,2) ! primal, dual, edge
[615]208#include "../kernels_unst/caldyn_fast.k90"
[658]209  STOP_TRACE
[615]210END SUBROUTINE compute_caldyn_fast
[638]211
[615]212!----------------------------- Unused -----------------------------
[638]213
[940]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
[615]236SUBROUTINE gradient(b,grad) BINDC(gradient)
[688]237  FIELD_MASS :: b
[698]238  FIELD_U    :: grad
[615]239  DECLARE_INDICES
240#include "../kernels_unst/gradient.k90"
241END SUBROUTINE
242!
243SUBROUTINE div(u,divu) BINDC(div)
[688]244  FIELD_MASS :: divu
[698]245  FIELD_U    :: u
[615]246  DECLARE_INDICES
[650]247  DECLARE_EDGES
[688]248  NUM :: div_ij
[615]249  !$OMP PARALLEL NUM_THREADS(nb_threads)
250#include "../kernels_unst/div.k90"
251  !$OMP END PARALLEL
252END SUBROUTINE
253
[784]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
[792]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
[615]277END MODULE caldyn_unstructured_mod
Note: See TracBrowser for help on using the repository browser.