source: codes/icosagcm/devel/src/kernels_unst/caldyn_solver.k90 @ 913

Last change on this file since 913 was 658, checked in by dubos, 7 years ago

devel/unstructured : updated kernels

File size: 3.1 KB
Line 
1   !--------------------------------------------------------------------------
2   !---------------------------- caldyn_solver ----------------------------------
3   !
4   ! Compute pressure (pres) and Exner function (pk)
5   ! kappa = R/Cp
6   ! 1-kappa = Cv/Cp
7   ! Cp/Cv = 1/(1-kappa)
8   gamma = 1./(1.-kappa)
9   vreff = Rd*Treff/preff ! reference specific volume
10   Cvd = 1./(cpp-Rd)
11   Rd_preff = kappa*cpp/preff
12   SELECT CASE(caldyn_thermo)
13   CASE(thermo_theta)
14      !$OMP DO SCHEDULE(STATIC)
15      DO ij = 1, primal_num
16         !DIR$ SIMD
17         DO l = 1, llm
18            rho_ij = 1./(geopot(l+1,ij)-geopot(l,ij))
19            rho_ij = rho_ij*g*rhodz(l,ij)
20            X_ij = Rd_preff*theta(l,ij,1)*rho_ij
21            ! kappa.theta.rho = p/exner
22            ! => X = (p/p0)/(exner/Cp)
23            ! = (p/p0)^(1-kappa)
24            pres(l,ij) = preff*(X_ij**gamma) ! pressure
25            ! Compute Exner function (needed by compute_caldyn_fast)
26            ! other formulae possible if exponentiation is slow
27            pk(l,ij) = cpp*((pres(l,ij)/preff)**kappa) ! Exner
28         END DO
29      END DO
30      !$OMP END DO
31   CASE(thermo_entropy)
32      !$OMP DO SCHEDULE(STATIC)
33      DO ij = 1, primal_num
34         !DIR$ SIMD
35         DO l = 1, llm
36            rho_ij = 1./(geopot(l+1,ij)-geopot(l,ij))
37            rho_ij = rho_ij*g*rhodz(l,ij)
38            T_ij = Treff*exp( (theta(l,ij,1)+Rd*log(vreff*rho_ij))*Cvd )
39            pres(l,ij) = rho_ij*Rd*T_ij
40            pk(l,ij) = T_ij
41         END DO
42      END DO
43      !$OMP END DO
44   CASE DEFAULT
45      STOP
46   END SELECT
47   ! We need a barrier here because we compute pres above and do a vertical difference below
48   !$OMP BARRIER
49   !$OMP DO SCHEDULE(STATIC)
50   DO ij = 1, primal_num
51      l=1
52      ! Lower BC
53      dW(l,ij) = (1./g)*(pbot-rho_bot*(geopot(l,ij)-PHI_BOT(ij))-pres(l,ij)) - m_il(l,ij)
54      W(l,ij) = W(l,ij)+tau*dW(l,ij) ! update W
55      dPhi(l,ij) = g*g*W(l,ij)/m_il(l,ij)
56      !DIR$ SIMD
57      DO l = 2, llm
58         dW(l,ij) = (1./g)*(pres(l-1,ij)-pres(l,ij)) - m_il(l,ij)
59         W(l,ij) = W(l,ij)+tau*dW(l,ij) ! update W
60         dPhi(l,ij) = g*g*W(l,ij)/m_il(l,ij)
61      END DO
62      l=llm+1
63      ! Top BC
64      dW(l,ij) = (1./g)*(pres(l-1,ij)-ptop) - m_il(l,ij)
65      W(l,ij) = W(l,ij)+tau*dW(l,ij) ! update W
66      dPhi(l,ij) = g*g*W(l,ij)/m_il(l,ij)
67   END DO
68   !$OMP END DO
69   ! We need a barrier here because we update W above and do a vertical average below
70   !$OMP BARRIER
71   !$OMP DO SCHEDULE(STATIC)
72   DO ij = 1, primal_num
73      !DIR$ SIMD
74      DO l = 1, llm
75         ! compute du = -0.5*g^2.grad(w^2)
76         berni(l,ij) = (-.25*g*g)*((W(l,ij)/m_il(l,ij))**2 + (W(l+1,ij)/m_il(l+1,ij))**2 )
77      END DO
78   END DO
79   !$OMP END DO
80   !$OMP DO SCHEDULE(STATIC)
81   DO edge = 1, edge_num
82      ij_left = left(edge)
83      ij_right = right(edge)
84      !DIR$ SIMD
85      DO l = 1, llm
86         du(l,edge) = 1.*(berni(l,ij_left)-berni(l,ij_right))
87      END DO
88   END DO
89   !$OMP END DO
90   !---------------------------- caldyn_solver ----------------------------------
91   !--------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.