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

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

devel : added unstructured-mesh kernels

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