source: codes/icosagcm/devel/src/dynamics/compute_theta.F90 @ 922

Last change on this file since 922 was 917, checked in by dubos, 5 years ago

devel : DYSL for compute_theta

File size: 4.2 KB
Line 
1MODULE compute_theta_mod
2  USE grid_param, ONLY : llm, nqdyn
3  USE disvert_mod, ONLY : mass_dak, mass_dbk, caldyn_eta, eta_mass, ptop
4  IMPLICIT NONE
5  PRIVATE
6
7#include "../unstructured/unstructured.h90"
8
9  PUBLIC :: compute_theta_unst, compute_theta_hex, compute_theta_manual
10
11CONTAINS
12
13  ! Python/Fortran differences to be resolved at some point :
14
15  ! the Fortran driver prognoses ps/mass_col or rhodz depending on caldyn_eta
16  ! the Python driver prognoses rhodz even if caldyn_eta==eta_mass
17  ! so that the DOFs are the same whatever caldyn_eta
18
19  ! in the Fortran driver dak, dbk are 1D and based on pressure
20  ! => m = mass_dak(l)+(mass_col(ij)*g+ptop)*mass_dbk(l)
21  !    rhodz(CELL) = m/g
22  ! in the Python driver dak, dbk are 2D and based on mass
23  ! => rhodz(CELL) = MASS_DAK(CELL) + mass_col(HIDX(CELL))*MASS_DBK(CELL)
24
25#ifdef BEGIN_DYSL
26
27KERNEL(theta)
28  IF(caldyn_eta==eta_mass) THEN ! Compute mass
29    ! compute mass_col from rhodz
30    SEQUENCE_C1
31      PROLOGUE(0)
32        mass_col(HIDX(CELL))=0.
33      END_BLOCK
34      BODY('1,llm')
35          mass_col(HIDX(CELL)) = mass_col(HIDX(CELL)) + rhodz(CELL)
36      END_BLOCK
37    END_BLOCK
38    FORALL_CELLS_EXT()
39      ON_PRIMAL
40        rhodz(CELL) = MASS_DAK(CELL) + mass_col(HIDX(CELL))*MASS_DBK(CELL)
41      END_BLOCK
42    END_BLOCK
43  END IF
44  DO iq=1,nqdyn
45    FORALL_CELLS_EXT()
46      ON_PRIMAL
47        theta(CELL,iq) = theta_rhodz(CELL,iq)/rhodz(CELL)
48      END_BLOCK
49    END_BLOCK
50  END DO
51END_BLOCK
52
53KERNEL(compute_theta)
54  IF(caldyn_eta==eta_mass) THEN ! Compute mass
55     FORALL_CELLS_EXT()
56       ON_PRIMAL
57         m = MASS_DAK(CELL)+(mass_col(HIDX(CELL))*g+ptop)*MASS_DBK(CELL)
58         rhodz(CELL) = m/g
59        END_BLOCK
60     END_BLOCK
61  END IF 
62  DO iq=1,nqdyn
63     FORALL_CELLS_EXT()
64       ON_PRIMAL
65         theta(CELL,iq) = theta_rhodz(CELL,iq)/rhodz(CELL)
66       END_BLOCK
67     END_BLOCK
68  END DO
69END_BLOCK
70
71#endif END_DYSL
72
73  SUBROUTINE compute_theta_unst(mass_col,theta_rhodz, rhodz,theta)
74    USE ISO_C_BINDING, only : C_DOUBLE, C_FLOAT
75    USE data_unstructured_mod, ONLY : id_theta,primal_num,dual_num,edge_num, &
76         enter_trace, exit_trace
77    FIELD_PS :: mass_col
78    FIELD_MASS :: rhodz
79    FIELD_THETA :: theta, theta_rhodz
80    DECLARE_INDICES
81    NUM :: m
82    START_TRACE(id_theta, 3,0,0) ! primal, dual, edge 
83#define MASS_DAK(l,ij) mass_dak(l)
84#define MASS_DBK(l,ij) mass_dbk(l)
85#include "../kernels_unst/theta.k90"
86#undef MASS_DAK
87#undef MASS_DBK
88    STOP_TRACE
89  END SUBROUTINE compute_theta_unst
90
91  SUBROUTINE compute_theta_hex(mass_col,theta_rhodz, rhodz,theta)
92    USE icosa
93    USE trace, ONLY : trace_start, trace_end
94    USE omp_para, ONLY : ll_begin, ll_end
95    REAL(rstd),INTENT(IN)    :: mass_col(iim*jjm)
96    REAL(rstd),INTENT(IN)    :: theta_rhodz(iim*jjm,llm,nqdyn)
97    REAL(rstd),INTENT(INOUT) :: rhodz(iim*jjm,llm)
98    REAL(rstd),INTENT(OUT)   :: theta(iim*jjm,llm,nqdyn)
99    INTEGER :: ij,l,iq
100    REAL(rstd) :: m
101    CALL trace_start("compute_theta")
102#define MASS_DAK(ij,l) mass_dak(l)
103#define MASS_DBK(ij,l) mass_dbk(l)
104#include "../kernels_hex/compute_theta.k90"
105#undef MASS_DAK
106#undef MASS_DBK
107    CALL trace_end("compute_theta")
108  END SUBROUTINE compute_theta_hex
109 
110  SUBROUTINE compute_theta_manual(ps,theta_rhodz, rhodz,theta)
111    USE icosa
112    USE trace, ONLY : trace_start, trace_end
113    USE omp_para, ONLY : ll_begin, ll_end
114    REAL(rstd),INTENT(IN)    :: ps(iim*jjm)
115    REAL(rstd),INTENT(IN)    :: theta_rhodz(iim*jjm,llm,nqdyn)
116    REAL(rstd),INTENT(INOUT) :: rhodz(iim*jjm,llm)
117    REAL(rstd),INTENT(OUT)   :: theta(iim*jjm,llm,nqdyn)
118    INTEGER :: ij,l,iq
119    REAL(rstd) :: m
120    CALL trace_start("compute_theta")
121
122    IF(caldyn_eta==eta_mass) THEN ! Compute mass
123       DO l = ll_begin,ll_end
124          !DIR$ SIMD
125          DO ij=ij_begin_ext,ij_end_ext
126             m = mass_dak(l)+(ps(ij)*g+ptop)*mass_dbk(l) ! ps is actually Ms
127             rhodz(ij,l) = m/g
128          END DO
129       END DO
130    END IF
131
132    DO l = ll_begin,ll_end
133       DO iq=1,nqdyn
134          !DIR$ SIMD
135          DO ij=ij_begin_ext,ij_end_ext
136             theta(ij,l,iq) = theta_rhodz(ij,l,iq)/rhodz(ij,l)
137          END DO
138       END DO
139    END DO
140
141    CALL trace_end("compute_theta")
142  END SUBROUTINE compute_theta_manual
143 
144END MODULE compute_theta_mod
Note: See TracBrowser for help on using the repository browser.