source: codes/icosagcm/devel/src/kernels_hex/caldyn_solver.k90 @ 724

Last change on this file since 724 was 657, checked in by dubos, 7 years ago

devel/hex : updated kernels

File size: 3.2 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   DO l = ll_begin, ll_end
13      !DIR$ SIMD
14      DO ij=ij_begin_ext, ij_end_ext
15         SELECT CASE(caldyn_thermo)
16         CASE(thermo_theta)
17            rho_ij = 1./(geopot(ij,l+1)-geopot(ij,l))
18            rho_ij = rho_ij*g*rhodz(ij,l)
19            X_ij = Rd_preff*theta(ij,l,1)*rho_ij
20            ! kappa.theta.rho = p/exner
21            ! => X = (p/p0)/(exner/Cp)
22            ! = (p/p0)^(1-kappa)
23            pres(ij,l) = preff*(X_ij**gamma) ! pressure
24            ! Compute Exner function (needed by compute_caldyn_fast)
25            ! other formulae possible if exponentiation is slow
26            pk(ij,l) = cpp*((pres(ij,l)/preff)**kappa) ! Exner
27         CASE(thermo_entropy)
28            rho_ij = 1./(geopot(ij,l+1)-geopot(ij,l))
29            rho_ij = rho_ij*g*rhodz(ij,l)
30            T_ij = Treff*exp( (theta(ij,l,1)+Rd*log(vreff*rho_ij))*Cvd )
31            pres(ij,l) = rho_ij*Rd*T_ij
32            pk(ij,l) = T_ij
33         CASE DEFAULT
34            STOP
35         END SELECT
36      END DO
37   END DO
38   ! We need a barrier here because we compute pres above and do a vertical difference below
39   !$OMP BARRIER
40   IF (ll_begin==1) THEN
41      !DIR$ SIMD
42      DO ij=ij_begin_ext, ij_end_ext
43         ! Lower BC
44         dW(ij,1) = (1./g)*(pbot-rho_bot*(geopot(ij,1)-PHI_BOT(ij))-pres(ij,1)) - m_il(ij,1)
45         W(ij,1) = W(ij,1)+tau*dW(ij,1) ! update W
46         dPhi(ij,1) = g*g*W(ij,1)/m_il(ij,1)
47      END DO
48   END IF
49   DO l = ll_beginp1, ll_end
50      !DIR$ SIMD
51      DO ij=ij_begin_ext, ij_end_ext
52         dW(ij,l) = (1./g)*(pres(ij,l-1)-pres(ij,l)) - m_il(ij,l)
53         W(ij,l) = W(ij,l)+tau*dW(ij,l) ! update W
54         dPhi(ij,l) = g*g*W(ij,l)/m_il(ij,l)
55      END DO
56   END DO
57   IF(ll_endp1==llm+1) THEN
58      !DIR$ SIMD
59      DO ij=ij_begin_ext, ij_end_ext
60         ! Top BC
61         dW(ij,llm+1) = (1./g)*(pres(ij,llm+1 -1)-ptop) - m_il(ij,llm+1)
62         W(ij,llm+1) = W(ij,llm+1)+tau*dW(ij,llm+1) ! update W
63         dPhi(ij,llm+1) = g*g*W(ij,llm+1)/m_il(ij,llm+1)
64      END DO
65   END IF
66   ! We need a barrier here because we update W above and do a vertical average below
67   !$OMP BARRIER
68   DO l = ll_begin, ll_end
69      !DIR$ SIMD
70      DO ij=ij_begin_ext, ij_end_ext
71         ! compute du = -0.5*g^2.grad(w^2)
72         berni(ij,l) = (-.25*g*g)*((W(ij,l)/m_il(ij,l))**2 + (W(ij,l+1)/m_il(ij,l+1))**2 )
73      END DO
74   END DO
75   DO l = ll_begin, ll_end
76      !DIR$ SIMD
77      DO ij=ij_begin_ext, ij_end_ext
78         du(ij+u_right,l) = ne_right*(berni(ij,l)-berni(ij+t_right,l))
79         du(ij+u_lup,l) = ne_lup*(berni(ij,l)-berni(ij+t_lup,l))
80         du(ij+u_ldown,l) = ne_ldown*(berni(ij,l)-berni(ij+t_ldown,l))
81      END DO
82   END DO
83   !---------------------------- caldyn_solver ----------------------------------
84   !--------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.