source: codes/icosagcm/devel/src/kernels/caldyn_solver.k90 @ 568

Last change on this file since 568 was 563, checked in by dubos, 7 years ago

devel : added macro-generated code in source tree

File size: 3.5 KB
Line 
1   !--------------------------------------------------------------------------
2   !---------------------------- caldyn_solver ----------------------------------
3   IF (ll_begin==1) THEN
4      !DIR$ SIMD
5      DO ij=ij_begin_ext, ij_end_ext
6         m_il(ij,1) = .5*rhodz(ij,1)
7      END DO
8   END IF
9   DO l = ll_beginp1, ll_end
10      !DIR$ SIMD
11      DO ij=ij_begin_ext, ij_end_ext
12         m_il(ij,l) = .5*(rhodz(ij,l)+rhodz(ij,l-1))
13      END DO
14   END DO
15   IF(ll_endp1==llm+1) THEN
16      !DIR$ SIMD
17      DO ij=ij_begin_ext, ij_end_ext
18         m_il(ij,llm+1) = .5*rhodz(ij,llm+1 -1)
19      END DO
20   END IF
21   !
22   IF(tau>0) THEN ! solve implicit problem for geopotential
23      CALL compute_NH_geopot(tau,PHI_BOT_VAR, rhodz, m_il, theta, W, geopot)
24   END IF
25   !
26   ! Compute pressure (pres) and Exner function (pk)
27   ! kappa = R/Cp
28   ! 1-kappa = Cv/Cp
29   ! Cp/Cv = 1/(1-kappa)
30   gamma = 1./(1.-kappa)
31   vreff = Rd*Treff/preff ! reference specific volume
32   Cvd = cpp-Rd
33   DO l = ll_begin, ll_end
34      !DIR$ SIMD
35      DO ij=ij_begin_ext, ij_end_ext
36         SELECT CASE(caldyn_thermo)
37         CASE(thermo_theta)
38            rho_ij = g*rhodz(ij,l)/(geopot(ij,l+1)-geopot(ij,l))
39            X_ij = (cpp/preff)*kappa*theta(ij,l,1)*rho_ij
40            ! kappa.theta.rho = p/exner
41            ! => X = (p/p0)/(exner/Cp)
42            ! = (p/p0)^(1-kappa)
43            pres(ij,l) = preff*(X_ij**gamma) ! pressure
44            ! Compute Exner function (needed by compute_caldyn_fast)
45            ! other formulae possible if exponentiation is slow
46            pk(ij,l) = cpp*((pres(ij,l)/preff)**kappa) ! Exner
47         CASE(thermo_entropy)
48            rho_ij = g*rhodz(ij,l)/(geopot(ij,l+1)-geopot(ij,l))
49            T_ij = Treff*exp( (theta(ij,l,1)+Rd*log(vreff*rho_ij))/Cvd )
50            pres(ij,l) = rho_ij*Rd*T_ij
51            pk(ij,l) = T_ij
52         CASE DEFAULT
53            STOP
54         END SELECT
55      END DO
56   END DO
57   !$OMP BARRIER
58   IF (ll_begin==1) THEN
59      !DIR$ SIMD
60      DO ij=ij_begin_ext, ij_end_ext
61         ! Lower BC
62         dW(ij,1) = (1./g)*(pbot-rho_bot*(geopot(ij,1)-PHI_BOT(ij))-pres(ij,1)) - m_il(ij,1)
63         W(ij,1) = W(ij,1)+tau*dW(ij,1) ! update W
64         dPhi(ij,1) = g*g*W(ij,1)/m_il(ij,1)
65      END DO
66   END IF
67   DO l = ll_beginp1, ll_end
68      !DIR$ SIMD
69      DO ij=ij_begin_ext, ij_end_ext
70         dW(ij,l) = (1./g)*(pres(ij,l-1)-pres(ij,l)) - m_il(ij,l)
71         W(ij,l) = W(ij,l)+tau*dW(ij,l) ! update W
72         dPhi(ij,l) = g*g*W(ij,l)/m_il(ij,l)
73      END DO
74   END DO
75   IF(ll_endp1==llm+1) THEN
76      !DIR$ SIMD
77      DO ij=ij_begin_ext, ij_end_ext
78         ! Top BC
79         dW(ij,llm+1) = (1./g)*(pres(ij,llm+1 -1)-ptop) - m_il(ij,llm+1)
80         W(ij,llm+1) = W(ij,llm+1)+tau*dW(ij,llm+1) ! update W
81         dPhi(ij,llm+1) = g*g*W(ij,llm+1)/m_il(ij,llm+1)
82      END DO
83   END IF
84   DO l = ll_begin, ll_end
85      !DIR$ SIMD
86      DO ij=ij_begin_ext, ij_end_ext
87         ! compute du = -0.5*g^2.grad(w^2)
88         berni(ij,l) = (-.25*g*g)*((W(ij,l)/m_il(ij,l))**2 + (W(ij,l+1)/m_il(ij,l+1))**2 )
89      END DO
90   END DO
91   DO l = ll_begin, ll_end
92      !DIR$ SIMD
93      DO ij=ij_begin_ext, ij_end_ext
94         du(ij+u_right,l) = ne_right*(berni(ij,l)-berni(ij+t_right,l))
95         du(ij+u_lup,l) = ne_lup*(berni(ij,l)-berni(ij+t_lup,l))
96         du(ij+u_ldown,l) = ne_ldown*(berni(ij,l)-berni(ij+t_ldown,l))
97      END DO
98   END DO
99   !---------------------------- caldyn_solver ----------------------------------
100   !--------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.