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

Last change on this file since 1027 was 1027, checked in by dubos, 4 years ago

devel : towards conformity to F2008 standard

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