!-------------------------------------------------------------------------- !---------------------------- caldyn_solver ---------------------------------- ! ! Compute pressure (pres) and Exner function (pk) ! kappa = R/Cp ! 1-kappa = Cv/Cp ! Cp/Cv = 1/(1-kappa) gamma = 1./(1.-kappa) vreff = Rd*Treff/preff ! reference specific volume Cvd = 1./(cpp-Rd) Rd_preff = kappa*cpp/preff SELECT CASE(caldyn_thermo) CASE(thermo_theta) !$OMP DO SCHEDULE(STATIC) DO ij = 1, primal_num !DIR$ SIMD DO l = 1, llm rho_ij = 1./(geopot(l+1,ij)-geopot(l,ij)) rho_ij = rho_ij*g*rhodz(l,ij) X_ij = Rd_preff*theta(l,ij,1)*rho_ij ! kappa.theta.rho = p/exner ! => X = (p/p0)/(exner/Cp) ! = (p/p0)^(1-kappa) pres(l,ij) = preff*(X_ij**gamma) ! pressure ! Compute Exner function (needed by compute_caldyn_fast) ! other formulae possible if exponentiation is slow pk(l,ij) = cpp*((pres(l,ij)/preff)**kappa) ! Exner END DO END DO !$OMP END DO CASE(thermo_entropy) !$OMP DO SCHEDULE(STATIC) DO ij = 1, primal_num !DIR$ SIMD DO l = 1, llm rho_ij = 1./(geopot(l+1,ij)-geopot(l,ij)) rho_ij = rho_ij*g*rhodz(l,ij) T_ij = Treff*exp( (theta(l,ij,1)+Rd*log(vreff*rho_ij))*Cvd ) pres(l,ij) = rho_ij*Rd*T_ij pk(l,ij) = T_ij END DO END DO !$OMP END DO CASE DEFAULT STOP END SELECT ! We need a barrier here because we compute pres above and do a vertical difference below !$OMP BARRIER !$OMP DO SCHEDULE(STATIC) DO ij = 1, primal_num l=1 ! Lower BC dW(l,ij) = (1./g)*(pbot-rho_bot*(geopot(l,ij)-PHI_BOT(ij))-pres(l,ij)) - m_il(l,ij) W(l,ij) = W(l,ij)+tau*dW(l,ij) ! update W dPhi(l,ij) = g*g*W(l,ij)/m_il(l,ij) !DIR$ SIMD DO l = 2, llm dW(l,ij) = (1./g)*(pres(l-1,ij)-pres(l,ij)) - m_il(l,ij) W(l,ij) = W(l,ij)+tau*dW(l,ij) ! update W dPhi(l,ij) = g*g*W(l,ij)/m_il(l,ij) END DO l=llm+1 ! Top BC dW(l,ij) = (1./g)*(pres(l-1,ij)-ptop) - m_il(l,ij) W(l,ij) = W(l,ij)+tau*dW(l,ij) ! update W dPhi(l,ij) = g*g*W(l,ij)/m_il(l,ij) END DO !$OMP END DO ! We need a barrier here because we update W above and do a vertical average below !$OMP BARRIER !$OMP DO SCHEDULE(STATIC) DO ij = 1, primal_num !DIR$ SIMD DO l = 1, llm ! compute du = -0.5*g^2.grad(w^2) berni(l,ij) = (-.25*g*g)*((W(l,ij)/m_il(l,ij))**2 + (W(l+1,ij)/m_il(l+1,ij))**2 ) END DO END DO !$OMP END DO !$OMP DO SCHEDULE(STATIC) DO edge = 1, edge_num ij_left = left(edge) ij_right = right(edge) !DIR$ SIMD DO l = 1, llm du(l,edge) = 1.*(berni(l,ij_left)-berni(l,ij_right)) END DO END DO !$OMP END DO !---------------------------- caldyn_solver ---------------------------------- !--------------------------------------------------------------------------