Changeset 3985 for LMDZ6/branches/LMDZ-tracers/libf/dyn3dmem
- Timestamp:
- Sep 22, 2021, 6:11:35 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/branches/LMDZ-tracers/libf/dyn3dmem/dynetat0_loc.F90
r3957 r3985 7 7 !------------------------------------------------------------------------------- 8 8 USE parallel_lmdz 9 USE readTracFiles_mod, ONLY: known_phases, old_phases, nphases, phases_sep10 9 USE infotrac, ONLY: nqtot, niso, tracers, iTraPha, tnat, alpha_ideal, tra 11 USE netcdf, ONLY: NF90_OPEN, NF90_NOWRITE, NF90_INQ_VARID, NF90_INQUIRE_DIMENSION,&12 NF90_INQUIRE, NF90_CLOSE, NF90_GET_VAR, NF90_NoErr, NF90_INQUIRE_VARIABLE13 USE strings_mod, ONLY: strIdx10 USE netcdf, ONLY: NF90_OPEN, NF90_INQUIRE_DIMENSION, NF90_INQ_VARID, & 11 NF90_NOWRITE, NF90_CLOSE, NF90_INQUIRE_VARIABLE, NF90_GET_VAR, & 12 NF90_GET_ATT, NF90_NoErr, NF90_INQUIRE 14 13 USE control_mod, ONLY: planet_type 15 14 USE assert_eq_m, ONLY: assert_eq 16 15 USE comvert_mod, ONLY: pa,preff 17 USE comconst_mod, ONLY: cpp, daysec, dtvr, g, im, jm, kappa, lllm, omeg, rad 16 USE comconst_mod, ONLY: cpp, daysec, dtvr, g, im, jm, kappa, lllm, & 17 omeg, rad 18 18 USE logic_mod, ONLY: fxyhypb, ysinus 19 19 USE serre_mod, ONLY: clon, clat, grossismx, grossismy 20 USE temps_mod, ONLY: annee_ref, day_ini, day_ref, itau_dyn, start_time 21 USE ener_mod, ONLY: etot0, ptot0, ztot0, stot0, ang0 20 USE temps_mod, ONLY: annee_ref,day_ref,itau_dyn, & 21 start_time,day_ini 22 USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0 23 USE strings_mod, ONLY: strIdx 24 USE readTracFiles_mod, ONLY: known_phases, old_phases, nphases, phases_sep 22 25 23 26 IMPLICIT NONE … … 41 44 CHARACTER(LEN=256) :: sdum, var, modname, oldH2O 42 45 INTEGER, PARAMETER :: length=100 43 INTEGER :: iq, fID, vID, idecal, ix, ip, ierr 46 INTEGER :: iq, fID, vID, idecal, ix, ip, ierr, ib, ie, nglo 44 47 REAL :: time, tab_cntrl(length) !--- RUN PARAMS TABLE 45 48 TYPE(tra), POINTER :: tr … … 122 125 END IF 123 126 CALL err(NF90_GET_VAR(fID,vID,time),"get",var) 124 CALL get_var1("phisinit", phis, ijb_u, ije_u, ip1jmp1) 125 CALL get_var2("ucov", ucov, ijb_u, ije_u, ip1jmp1) 126 CALL get_var2("vcov", vcov, ijb_v, ije_v, ip1jm) 127 CALL get_var2("teta", teta, ijb_u, ije_u, ip1jmp1) 128 CALL get_var2("masse", masse, ijb_u, ije_u, ip1jmp1) 129 CALL get_var1("ps", ps, ijb_u, ije_u, ip1jmp1) 127 ib = ijb_v; ie = ije_v; nglo = ip1jm 128 CALL get_var2("vcov", vcov(ib:ie,:), ib, ie, nglo) 129 ib = ijb_u; ie = ije_u; nglo = ip1jmp1 130 CALL get_var2("ucov", ucov(ib:ie,:), ib, ie, nglo) 131 CALL get_var2("teta", teta(ib:ie,:), ib, ie, nglo) 132 CALL get_var2("masse", masse(ib:ie,:), ib, ie, nglo) 133 CALL get_var1("phisinit", phis(ib:ie), ib, ie) 134 CALL get_var1("ps", ps(ib:ie), ib, ie) 130 135 131 136 !--- Tracers … … 135 140 ix = strIdx([('H2O'//phases_sep//known_phases(ip:ip), ip=1, nphases)], var) 136 141 IF(NF90_INQ_VARID(fID, var, vID) == NF90_NoErr) THEN 137 CALL get_var2(var, q( :,:,iq), ijb_u, ije_u, ip1jmp1)142 CALL get_var2(var, q(ib:ie,:,iq), ib, ie, nglo) 138 143 #ifdef INCA 139 144 ELSE IF(NF90_INQ_VARID(fID, 'OX', vID) == NF90_NoErr .AND. var == 'O3') THEN 140 145 WRITE(lunout,*)TRIM(modname)//': Tracer <O3> is missing => initialized to OX' 141 CALL get_var2('OX', q( :,:,iq), ijb_u, ije_u, ip1jmp1)146 CALL get_var2('OX', q(ib:ie,:,iq), ib, ie, nglo) 142 147 #endif 143 148 ELSE IF(ix /= 0) THEN !--- Old file, water: H2Ov/l/i instead of H2O-g/-l/-s … … 145 150 IF(NF90_INQ_VARID(fID, oldH2O, vID) == NF90_NoErr) THEN 146 151 WRITE(lunout,*)TRIM(modname)//': Tracer <'//TRIM(var)//'> is missing => initialized to '//TRIM(oldH2O) 147 CALL get_var2(oldH2O, q( :,:,iq), ijb_u, ije_u, ip1jmp1)152 CALL get_var2(oldH2O, q(ib:ie,:,iq), ib, ie, nglo) 148 153 END IF 149 154 ELSE 150 155 WRITE(lunout,*)TRIM(modname)//': Tracer <'//TRIM(var)//'> is missing => initialized to zero' 151 q(i jb_u:ije_u,:,iq)=0.156 q(ib:ie,:,iq)=0. 152 157 !--- CRisi: for isotopes, theoretical initialization using very simplified Rayleigh distillation law 153 158 IF(niso > 0 .AND. tr%iso_num > 0) THEN … … 179 184 180 185 181 SUBROUTINE get_var1(var, v, ib, ie, n_glo) 186 SUBROUTINE get_var1(var, v, ib, ie) 187 !--- Usable for fields up to rank 4 with single time record (last index) 188 !--- Result: stacked in a vector. Used for 2D (single layer) fields. 182 189 CHARACTER(LEN=*), INTENT(IN) :: var 183 190 REAL, INTENT(OUT) :: v(:) 184 INTEGER, OPTIONAL, INTENT(IN) :: ib, ie , n_glo191 INTEGER, OPTIONAL, INTENT(IN) :: ib, ie 185 192 REAL, ALLOCATABLE :: w(:,:,:,:), v_glo(:) 186 INTEGER :: n n(4), dids(4), k, nd, ntot193 INTEGER :: n(4), dids(4), k, nd, ntot 187 194 CALL err(NF90_INQ_VARID(fID, var, vID), "inq", var) 188 195 ierr = NF90_INQUIRE_VARIABLE(fID, vID, dimids=dids, ndims=nd) 189 nn(:) = 1; DO k=1,nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=nn(k)); END DO 190 ntot = PRODUCT(nn(1:nd)) 191 ALLOCATE(w(nn(1), nn(2), nn(3), nn(4))) 196 n(:) = 1; DO k = 1, nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=n(k)); END DO 197 IF(is_rec(fID, dids(nd)) .AND. n(nd) /= 1) & 198 CALL abort_gcm(TRIM(modname), 'Several records records for <'//TRIM(var)//'>') 199 ntot = PRODUCT(n(1:nd)) 200 ALLOCATE(w(n(1), n(2), n(3), n(4)), v_glo(ntot)) 192 201 CALL err(NF90_GET_VAR(fID, vID, w), "get", var) 193 ALLOCATE(v_glo(ntot)); v_glo=RESHAPE(w, [ntot]); DEALLOCATE(w) 194 IF(PRESENT(n_glo).AND.PRESENT(ib).AND.PRESENT(ie)) THEN 195 IF(ntot/=n_glo) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"') 196 v(ib:ie) = v_glo(ib:ie) 197 ELSE 198 v(:) = v_glo(:) 199 END IF 202 v_glo(:) = RESHAPE(w, [ntot]); DEALLOCATE(w) 203 IF(PRESENT(ib).AND.PRESENT(ie)) THEN; v(:) = v_glo(ib:ie); ELSE; v(:) = v_glo(:); END IF 200 204 DEALLOCATE(v_glo) 201 205 END SUBROUTINE get_var1 … … 203 207 204 208 SUBROUTINE get_var2(var, v, ib, ie, n_glo) 209 !--- Usable for fields up to rank 4 with one or several time records (last index) 210 !--- Result: stacked in a 2D array (1st/2nd index: horizontal/vertical). Used for 3D (several layers) fields. 205 211 CHARACTER(LEN=*), INTENT(IN) :: var 206 212 REAL, INTENT(OUT) :: v(:,:) 207 213 INTEGER, INTENT(IN) :: ib, ie, n_glo 208 214 REAL, ALLOCATABLE :: w(:,:,:,:), v_glo(:,:) 209 INTEGER :: n n(4), dids(4), k, nd, nh, nv, tid215 INTEGER :: n(4), dids(4), k, nd, nh, nv, tid 210 216 CALL err(NF90_INQ_VARID(fID, var, vID), "inq", var) 211 217 ierr = NF90_INQUIRE_VARIABLE(fID, vID, dimids=dids, ndims=nd) 212 nn(:) = 1; DO k=1,nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=nn(k)); END DO 213 IF(NF90_INQUIRE(fID, unlimitedDimId=tid) == NF90_NOERR) THEN 214 nh = PRODUCT(nn(1:nd-2)); nv = nn(nd-1); nn(nd) = 1 218 n(:) = 1; DO k = 1, nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=n(k)); END DO 219 IF(is_rec(fID, dids(nd))) THEN 220 IF(n(nd) /= 1) CALL abort_gcm(TRIM(modname), 'Several records records for <'//TRIM(var)//'>.') 221 nh = PRODUCT(n(1:nd-2)); nv = n(nd-1) 215 222 ELSE 216 nh = PRODUCT(nn(1:nd-1)); nv = nn(nd) 217 END IF 218 ALLOCATE(w(nn(1), nn(2), nn(3), nn(4))) 223 nh = PRODUCT(n(1:nd )); nv = n(nd) 224 END IF 225 IF(nh/=n_glo .OR. nv/=llm) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"') 226 ALLOCATE(w(n(1), n(2), n(3), n(4)), v_glo(nh,nv)) 219 227 CALL err(NF90_GET_VAR(fID, vID, w), "get", var) 220 ALLOCATE(v_glo(nh, nv)); v_glo = RESHAPE(w, [nh, nv]); DEALLOCATE(w) 221 IF(nh/=n_glo .OR. nv/=llm) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"') 222 v(ib:ie,:) = v_glo(ib:ie,:) 228 v_glo(:,:) = RESHAPE(w, [nh, nv]); DEALLOCATE(w) 229 v(:,:) = v_glo(ib:ie,:) 223 230 DEALLOCATE(v_glo) 224 231 END SUBROUTINE get_var2 232 233 234 LOGICAL FUNCTION is_rec(fID, did) RESULT(lrec) 235 !--- Check whether the file has a record dimension, detected as UNLIMITED diemnsion or using the attribute "units". 236 INTEGER, INTENT(IN) :: fID, did 237 INTEGER :: vid 238 CHARACTER(LEN=256) :: recn, ratt 239 !--- Check the "units" attribute of the last dimensional variable to detect record axis. 240 lrec = NF90_INQUIRE_DIMENSION (fID, did, name=recn) == NF90_NOERR 241 IF(lrec) lrec = NF90_INQ_VARID (fID, recn, vid) == NF90_NOERR 242 IF(lrec) lrec = NF90_GET_ATT (fID, vid, "units", ratt)== NF90_NOERR 243 IF(lrec) lrec = INDEX(ratt, " since ") /= 0 244 END FUNCTION is_rec 225 245 226 246
Note: See TracChangeset
for help on using the changeset viewer.