SUBROUTINE dynetat0_loc(fichnom,vcov,ucov,teta,q,masse,ps,phis,time) ! !------------------------------------------------------------------------------- ! Authors: P. Le Van , L.Fairhead !------------------------------------------------------------------------------- ! Purpose: Initial state reading. !------------------------------------------------------------------------------- USE iniprint_mod_h USE comgeom_mod_h USE parallel_lmdz USE infotrac, ONLY: nqtot, tracers, niso, iqIsoPha, iH2O, isoName, & new2oldH2O, newHNO3, oldHNO3 USE strings_mod, ONLY: maxlen, msg, strStack, num2str, strIdx USE netcdf, ONLY: NF90_OPEN, NF90_NOWRITE, NF90_INQUIRE_DIMENSION, NF90_INQ_VARID, & NF90_CLOSE, NF90_GET_VAR, NF90_INQUIRE_VARIABLE, NF90_NoErr USE control_mod, ONLY: planet_type USE assert_eq_m, ONLY: assert_eq USE comvert_mod, ONLY: pa,preff USE comconst_mod, ONLY: cpp, daysec, dtvr, g, im, jm, kappa, lllm, omeg, rad USE logic_mod, ONLY: fxyhypb, ysinus USE serre_mod, ONLY: clon, clat, grossismx, grossismy USE temps_mod, ONLY: annee_ref, day_ini, day_ref, itau_dyn, start_time USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0 USE IOIPSL, ONLY: getin USE iso_params_mod ! tnat_* and alpha_ideal_* USE lmdz_cppkeys_wrapper, ONLY: CPPKEY_INCA, CPPKEY_REPROBUS USE dimensions_mod, ONLY: iim, jjm, llm, ndm USE paramet_mod_h IMPLICIT NONE !=============================================================================== ! Arguments: CHARACTER(LEN=*), INTENT(IN) :: fichnom !--- FILE NAME REAL, INTENT(OUT) :: vcov(ijb_v:ije_v,llm) !--- V COVARIANT WIND REAL, INTENT(OUT) :: ucov(ijb_u:ije_u,llm) !--- U COVARIANT WIND REAL, INTENT(OUT) :: teta(ijb_u:ije_u,llm) !--- POTENTIAL TEMP. REAL, INTENT(OUT) :: q(ijb_u:ije_u,llm,nqtot)!--- TRACERS REAL, INTENT(OUT) :: masse(ijb_u:ije_u,llm) !--- MASS PER CELL REAL, INTENT(OUT) :: ps(ijb_u:ije_u) !--- GROUND PRESSURE REAL, INTENT(OUT) :: phis(ijb_u:ije_u) !--- GEOPOTENTIAL !=============================================================================== ! Local variables: CHARACTER(LEN=maxlen) :: mesg, var, modname, oldVar INTEGER, PARAMETER :: length=100 INTEGER :: iq, fID, vID, idecal, ierr, iqParent, iName, iZone, iPhase, ix REAL :: time,tab_cntrl(length) !--- RUN PARAMS TABLE REAL :: tnat, alpha_ideal REAL, ALLOCATABLE :: vcov_glo(:,:),masse_glo(:,:), ps_glo(:) REAL, ALLOCATABLE :: ucov_glo(:,:), q_glo(:,:), phis_glo(:) REAL, ALLOCATABLE :: teta_glo(:,:) LOGICAL :: lSkip, ll, ltnat1 !------------------------------------------------------------------------------- modname="dynetat0_loc" !--- Initial state file opening var=fichnom CALL err(NF90_OPEN(var,NF90_NOWRITE,fID),"open",var) CALL get_var1("controle",tab_cntrl) !!! AS: idecal is a hack to be able to read planeto starts... !!! .... while keeping everything OK for LMDZ EARTH IF(planet_type=="generic") THEN CALL msg('NOTE NOTE NOTE : Planeto-like start files', modname) idecal = 4 annee_ref = 2000 ELSE CALL msg('NOTE NOTE NOTE : Earth-like start files', modname) idecal = 5 annee_ref = tab_cntrl(5) END IF im = tab_cntrl(1) jm = tab_cntrl(2) lllm = tab_cntrl(3) day_ref = tab_cntrl(4) rad = tab_cntrl(idecal+1) omeg = tab_cntrl(idecal+2) g = tab_cntrl(idecal+3) cpp = tab_cntrl(idecal+4) kappa = tab_cntrl(idecal+5) daysec = tab_cntrl(idecal+6) dtvr = tab_cntrl(idecal+7) etot0 = tab_cntrl(idecal+8) ptot0 = tab_cntrl(idecal+9) ztot0 = tab_cntrl(idecal+10) stot0 = tab_cntrl(idecal+11) ang0 = tab_cntrl(idecal+12) pa = tab_cntrl(idecal+13) preff = tab_cntrl(idecal+14) ! clon = tab_cntrl(idecal+15) clat = tab_cntrl(idecal+16) grossismx = tab_cntrl(idecal+17) grossismy = tab_cntrl(idecal+18) ! IF ( tab_cntrl(idecal+19)==1. ) THEN fxyhypb = .TRUE. ! dzoomx = tab_cntrl(25) ! dzoomy = tab_cntrl(26) ! taux = tab_cntrl(28) ! tauy = tab_cntrl(29) ELSE fxyhypb = .FALSE. ysinus = tab_cntrl(idecal+22)==1. END IF day_ini = tab_cntrl(30) itau_dyn = tab_cntrl(31) start_time = tab_cntrl(32) !------------------------------------------------------------------------------- CALL msg('rad, omeg, g, cpp, kappa = '//TRIM(strStack(num2str([rad,omeg,g,cpp,kappa]))), modname) CALL check_dim(im,iim,'im','im') CALL check_dim(jm,jjm,'jm','jm') CALL check_dim(lllm,llm,'lm','lllm') CALL get_var1("rlonu",rlonu) CALL get_var1("rlatu",rlatu) CALL get_var1("rlonv",rlonv) CALL get_var1("rlatv",rlatv) CALL get_var1("cu" ,cu) CALL get_var1("cv" ,cv) CALL get_var1("aire",aire) var="temps" IF(NF90_INQ_VARID(fID,var,vID)/=NF90_NoErr) THEN CALL msg('missing field <temps> ; trying with <Time>', modname) var="Time" CALL err(NF90_INQ_VARID(fID,var,vID),"inq",var) END IF CALL err(NF90_GET_VAR(fID,vID,time),"get",var) ALLOCATE(phis_glo(ip1jmp1)) CALL get_var1("phisinit",phis_glo) phis (ijb_u:ije_u) =phis_glo(ijb_u:ije_u); DEALLOCATE(phis_glo) ALLOCATE(ucov_glo(ip1jmp1,llm)) CALL get_var2("ucov",ucov_glo) ucov (ijb_u:ije_u,:)=ucov_glo(ijb_u:ije_u,:); DEALLOCATE(ucov_glo) ALLOCATE(vcov_glo(ip1jm,llm)) CALL get_var2("vcov",vcov_glo) vcov (ijb_v:ije_v,:)=vcov_glo(ijb_v:ije_v,:); DEALLOCATE(vcov_glo) ALLOCATE(teta_glo(ip1jmp1,llm)) CALL get_var2("teta",teta_glo) teta (ijb_u:ije_u,:)=teta_glo(ijb_u:ije_u,:); DEALLOCATE(teta_glo) ALLOCATE(masse_glo(ip1jmp1,llm)) CALL get_var2("masse",masse_glo) masse(ijb_u:ije_u,:)=masse_glo(ijb_u:ije_u,:); DEALLOCATE(masse_glo) ALLOCATE(ps_glo(ip1jmp1)) CALL get_var1("ps",ps_glo) ps (ijb_u:ije_u) = ps_glo(ijb_u:ije_u); DEALLOCATE(ps_glo) !--- Tracers ALLOCATE(q_glo(ip1jmp1,llm)) ll = .FALSE. IF (CPPKEY_REPROBUS) THEN ll = NF90_INQ_VARID(fID, 'HNO3tot', vID) /= NF90_NoErr !--- DETECT OLD REPRO start.nc FILE END IF ltnat1 = .TRUE.; CALL getin('tnateq1', ltnat1) DO iq=1,nqtot var = tracers(iq)%name oldVar = new2oldH2O(var) lSkip = ll .AND. var == 'HNO3' !--- FORCE "HNO3_g" READING FOR "HNO3" IF (CPPKEY_REPROBUS) THEN ix = strIdx(newHNO3, var); IF(ix /= 0) oldVar = oldHNO3(ix) !--- REPROBUS HNO3 exceptions END IF IF (CPPKEY_INCA) THEN IF(var == 'O3') oldVar = 'OX' !--- DEAL WITH INCA OZONE EXCEPTION END IF !-------------------------------------------------------------------------------------------------------------------------- IF(NF90_INQ_VARID(fID, var, vID) == NF90_NoErr .AND. .NOT.lSkip) THEN !=== REGULAR CASE: AVAILABLE VARIABLE CALL get_var2(var,q_glo); q(ijb_u:ije_u,:,iq)=q_glo(ijb_u:ije_u,:) !-------------------------------------------------------------------------------------------------------------------------- ELSE IF(NF90_INQ_VARID(fID, oldVar, vID) == NF90_NoErr) THEN !=== TRY WITH ALTERNATE NAME CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to <'//TRIM(oldVar)//'>', modname) CALL get_var2(oldVar, q_glo); q(ijb_u:ije_u,:,iq)=q_glo(ijb_u:ije_u,:) !-------------------------------------------------------------------------------------------------------------------------- ELSE IF(tracers(iq)%iso_iGroup == iH2O .AND. niso > 0) THEN !=== WATER ISOTOPES iName = tracers(iq)%iso_iName iPhase = tracers(iq)%iso_iPhase iqParent = tracers(iq)%iqParent IF(tracers(iq)%iso_iZone == 0) THEN IF(ltnat1) THEN tnat = 1.0 alpha_ideal = 1.0 CALL msg(' !!! Beware: alpha_ideal put to 1 !!!', modname) ELSE SELECT CASE(isoName(iName)) CASE('H216O'); tnat = tnat_H216O; alpha_ideal = alpha_ideal_H216O CASE('H217O'); tnat = tnat_H217O; alpha_ideal = alpha_ideal_H217O CASE('H218O'); tnat = tnat_H218O; alpha_ideal = alpha_ideal_H218O CASE('HDO'); tnat = tnat_HDO; alpha_ideal = alpha_ideal_HDO CASE('HTO'); tnat = tnat_HTO; alpha_ideal = alpha_ideal_HTO CASE DEFAULT; CALL abort_gcm(TRIM(modname),'unknown isotope "'//TRIM(isoName(iName))//'" ; check tracer.def file',1) END SELECT END IF CALL msg('Missing tracer <'//TRIM(var)//'> => initialized with a simplified Rayleigh distillation law.', modname) q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqParent)*tnat*(q(ijb_u:ije_u,:,iqParent)/30.e-3)**(alpha_ideal-1.) ! Camille 9 mars 2023: point de vigilence: initialisation incohérente ! avec celle de xt_ancien dans la physiq. ELSE CALL msg('Missing tracer <'//TRIM(var)//'> => initialized to its parent isotope concentration.', modname) ! Camille 9 mars 2023: attention!! seuls les tags qui correspondent à ! izone=izone_init (définie dans isotrac_mod) sont initialisés comme ! les parents. Sinon, c'est nul. ! j'ai fait ça en attendant, mais il faudrait initialiser proprement en ! remplacant 1 par izone_init dans la ligne qui suit. IF(tracers(iq)%iso_iZone == 1) THEN q(ijb_u:ije_u,:,iq) = q(ijb_u:ije_u,:,iqIsoPha(iName,iPhase)) ELSE q(ijb_u:ije_u,:,iq) = 0. ENDIF END IF !-------------------------------------------------------------------------------------------------------------------------- ELSE !=== MISSING: SET TO 0 CALL msg('missing tracer <'//TRIM(var)//'> => initialized to zero', modname) q(ijb_u:ije_u,:,iq)=0. !-------------------------------------------------------------------------------------------------------------------------- END IF END DO DEALLOCATE(q_glo) CALL err(NF90_CLOSE(fID),"close",fichnom) day_ini=day_ini+INT(time) time=time-INT(time) CONTAINS SUBROUTINE check_dim(n1,n2,str1,str2) INTEGER, INTENT(IN) :: n1, n2 CHARACTER(LEN=*), INTENT(IN) :: str1, str2 CHARACTER(LEN=maxlen) :: s1, s2 IF(n1/=n2) CALL abort_gcm(TRIM(modname), 'value of "'//TRIM(str1)//'" = '//TRIM(num2str(n1))// & ' read in starting file differs from gcm value of "'//TRIM(str2)//'" = '//TRIM(num2str(n2)), 1) END SUBROUTINE check_dim SUBROUTINE get_var1(var,v) CHARACTER(LEN=*), INTENT(IN) :: var REAL, INTENT(OUT) :: v(:) REAL, ALLOCATABLE :: w2(:,:), w3(:,:,:) INTEGER :: nn(3), dids(3), k, nd, ntot CALL err(NF90_INQ_VARID(fID,var,vID),"inq",var) ierr=NF90_INQUIRE_VARIABLE(fID,vID,ndims=nd) IF(nd==1) THEN CALL err(NF90_GET_VAR(fID,vID,v),"get",var); RETURN END IF ierr=NF90_INQUIRE_VARIABLE(fID,vID,dimids=dids) DO k=1,nd; ierr=NF90_INQUIRE_DIMENSION(fID,dids(k),len=nn(k)); END DO ntot=PRODUCT(nn(1:nd)) SELECT CASE(nd) CASE(2); ALLOCATE(w2(nn(1),nn(2))) CALL err(NF90_GET_VAR(fID,vID,w2),"get",var) v=RESHAPE(w2,[ntot]); DEALLOCATE(w2) CASE(3); ALLOCATE(w3(nn(1),nn(2),nn(3))) CALL err(NF90_GET_VAR(fID,vID,w3),"get",var) v=RESHAPE(w3,[ntot]); DEALLOCATE(w3) END SELECT END SUBROUTINE get_var1 SUBROUTINE get_var2(var,v) CHARACTER(LEN=*), INTENT(IN) :: var REAL, INTENT(OUT) :: v(:,:) REAL, ALLOCATABLE :: w4(:,:,:,:), w3(:,:,:) INTEGER :: nn(4), dids(4), k, nd CALL err(NF90_INQ_VARID(fID,var,vID),"inq",var) ierr=NF90_INQUIRE_VARIABLE(fID,vID,ndims=nd) IF(nd==1) THEN CALL err(NF90_GET_VAR(fID,vID,v),"get",var); RETURN END IF ierr=NF90_INQUIRE_VARIABLE(fID,vID,dimids=dids) DO k=1,nd; ierr=NF90_INQUIRE_DIMENSION(fID,dids(k),len=nn(k)); END DO SELECT CASE(nd) CASE(3); ALLOCATE(w3(nn(1),nn(2),nn(3))) CALL err(NF90_GET_VAR(fID,vID,w3),"get",var) v=RESHAPE(w3,[nn(1)*nn(2),nn(3)]); DEALLOCATE(w3) CASE(4); ALLOCATE(w4(nn(1),nn(2),nn(3),nn(4))) CALL err(NF90_GET_VAR(fID,vID,w4),"get",var) v=RESHAPE(w4,[nn(1)*nn(2),nn(3)]); DEALLOCATE(w4) END SELECT END SUBROUTINE get_var2 SUBROUTINE err(ierr,typ,nam) INTEGER, INTENT(IN) :: ierr !--- NetCDF ERROR CODE CHARACTER(LEN=*), INTENT(IN) :: typ !--- TYPE OF OPERATION CHARACTER(LEN=*), INTENT(IN) :: nam !--- FIELD/FILE NAME IF(ierr==NF90_NoERR) RETURN SELECT CASE(typ) CASE('inq'); mesg="Field <"//TRIM(nam)//"> is missing" CASE('get'); mesg="Reading failed for <"//TRIM(nam)//">" CASE('open'); mesg="File opening failed for <"//TRIM(nam)//">" CASE('close'); mesg="File closing failed for <"//TRIM(nam)//">" END SELECT CALL ABORT_gcm(TRIM(modname),TRIM(mesg),ierr) END SUBROUTINE err END SUBROUTINE dynetat0_loc