[816] | 1 | subroutine cellmass(infid,latlength,lonlength,altlength,timelength, & |
---|
| 2 | lmdflag,deltalon,deltalat,latrad,plev,ps,grav,rayon, & |
---|
| 3 | dmass ) |
---|
| 4 | |
---|
| 5 | implicit none |
---|
| 6 | |
---|
| 7 | include "netcdf.inc" ! NetCDF definitions |
---|
| 8 | |
---|
| 9 | ! arguments |
---|
| 10 | integer infid ! NetCDF input file ID |
---|
| 11 | integer lonlength ! # of grid points along longitude |
---|
| 12 | integer latlength ! # of grid points along latitude |
---|
| 13 | integer altlength ! # of grid point along altitude (of input datasets) |
---|
| 14 | integer timelength ! # of points along time |
---|
| 15 | logical lmdflag ! true=LMD, false=CAM |
---|
| 16 | real :: deltalat,deltalon ! lat and lon intervals in radians |
---|
| 17 | real,dimension(latlength) :: latrad ! latitudes in radians |
---|
| 18 | real,dimension(altlength) :: plev ! Pressure levels (Pa) |
---|
| 19 | real,dimension(lonlength,latlength,timelength),intent(in) :: ps ! surface pressure |
---|
| 20 | real,dimension(lonlength,latlength,altlength,timelength),intent(in) :: grav,rayon |
---|
| 21 | real,dimension(lonlength,latlength,altlength,timelength),intent(out) :: dmass |
---|
| 22 | |
---|
| 23 | !local |
---|
| 24 | character (len=64) :: text ! to store some text |
---|
| 25 | real,dimension(:),allocatable :: aps,bps ! hybrid vertical coordinates |
---|
| 26 | real,dimension(:,:,:,:),allocatable :: press ! GCM atmospheric pressure |
---|
| 27 | real,dimension(:),allocatable :: pp ! Pressure levels (Pa) |
---|
| 28 | real,dimension(:,:,:,:),allocatable :: deltap ! pressure thickness of each layer (Pa) |
---|
| 29 | integer ierr,ierr1,ierr2 ! NetCDF routines return codes |
---|
| 30 | integer i,j,ilon,ilat,ilev,itim ! for loops |
---|
| 31 | real :: tmpp ! temporary pressure |
---|
| 32 | real :: p0 ! GCM reference pressure |
---|
| 33 | integer tmpvarid |
---|
| 34 | real :: miss_val=9.99e+33 ! special "missing value" to specify missing data |
---|
| 35 | real,parameter :: miss_val_def=9.99e+33 ! default value for "missing value" |
---|
| 36 | |
---|
| 37 | include "planet.h" |
---|
| 38 | |
---|
| 39 | !=============================================================================== |
---|
| 40 | ! 2.2.1 Pressure intervals |
---|
| 41 | !=============================================================================== |
---|
| 42 | allocate(deltap(lonlength,latlength,altlength,timelength)) |
---|
| 43 | allocate(press(lonlength,latlength,altlength,timelength)) |
---|
| 44 | allocate(pp(altlength)) |
---|
| 45 | |
---|
| 46 | if(lmdflag) then ! LMD vs CAM |
---|
| 47 | text="pres" |
---|
| 48 | call get_var4d(infid,lonlength,latlength,altlength,timelength,text,press,ierr1,ierr2) |
---|
| 49 | if (ierr1.ne.NF_NOERR) then |
---|
| 50 | ! assume we are using _P files |
---|
| 51 | do itim=1,timelength |
---|
| 52 | do ilon=1,lonlength |
---|
| 53 | do ilat=1,latlength |
---|
| 54 | press(ilon,ilat,:,itim) = plev |
---|
| 55 | enddo |
---|
| 56 | enddo |
---|
| 57 | enddo |
---|
| 58 | else |
---|
| 59 | if (ierr2.ne.NF_NOERR) stop "Error: Failed reading pres" |
---|
| 60 | endif |
---|
| 61 | |
---|
| 62 | else ! LMD vs CAM |
---|
| 63 | ierr=NF_INQ_VARID(infid,"P0",tmpvarid) |
---|
| 64 | if (ierr.ne.NF_NOERR) then |
---|
| 65 | write(*,*) "Failed to get P0 ID, used psref=",psref |
---|
| 66 | p0=psref |
---|
| 67 | else |
---|
| 68 | ierr=NF_GET_VAR_REAL(infid,tmpvarid,p0) |
---|
| 69 | if (ierr.ne.NF_NOERR) then |
---|
| 70 | write(*,*) "Failed reading reference pressure, used psref=",psref |
---|
| 71 | p0=psref |
---|
| 72 | endif |
---|
| 73 | endif |
---|
| 74 | ! hybrid coordinate aps/hyam |
---|
| 75 | text="hyam" |
---|
| 76 | ierr=NF_INQ_VARID(infid,text,tmpvarid) |
---|
| 77 | if (ierr.ne.NF_NOERR) then |
---|
| 78 | stop "Error: Could not find aps/hyam coordinates" |
---|
| 79 | else |
---|
| 80 | allocate(aps(altlength)) |
---|
| 81 | ierr=NF_GET_VAR_REAL(infid,tmpvarid,aps) |
---|
| 82 | if (ierr.ne.NF_NOERR) then |
---|
| 83 | stop "Error: Failed reading aps/hyam" |
---|
| 84 | endif |
---|
| 85 | call reverselev(altlength,aps) |
---|
| 86 | endif |
---|
| 87 | |
---|
| 88 | ! hybrid coordinate hybm |
---|
| 89 | text="hybm" |
---|
| 90 | ierr=NF_INQ_VARID(infid,text,tmpvarid) |
---|
| 91 | if (ierr.ne.NF_NOERR) then |
---|
| 92 | stop "Error: Failed to get bps/hybm ID" |
---|
| 93 | else |
---|
| 94 | allocate(bps(altlength)) |
---|
| 95 | ierr=NF_GET_VAR_REAL(infid,tmpvarid,bps) |
---|
| 96 | if (ierr.ne.NF_NOERR) then |
---|
| 97 | stop "Error: Failed reading bps/hybm" |
---|
| 98 | endif |
---|
| 99 | call reverselev(altlength,bps) |
---|
| 100 | endif |
---|
| 101 | |
---|
| 102 | aps=aps*p0 |
---|
| 103 | |
---|
| 104 | do itim=1,timelength |
---|
| 105 | do ilev=1,altlength |
---|
| 106 | do ilat=1,latlength |
---|
| 107 | do ilon=1,lonlength |
---|
| 108 | press(ilon,ilat,ilev,itim)=aps(ilev)+bps(ilev)*ps(ilon,ilat,itim) |
---|
| 109 | enddo |
---|
| 110 | enddo |
---|
| 111 | enddo |
---|
| 112 | enddo |
---|
| 113 | |
---|
| 114 | endif ! LMD vs CAM |
---|
| 115 | |
---|
| 116 | do itim=1,timelength |
---|
| 117 | |
---|
| 118 | do ilon=1,lonlength |
---|
| 119 | do ilat=1,latlength |
---|
| 120 | tmpp=ps(ilon,ilat,itim) |
---|
| 121 | pp=press(ilon,ilat,:,itim) |
---|
| 122 | if (tmpp.ge.pp(1)) then |
---|
| 123 | deltap(ilon,ilat,1,itim)= tmpp - exp((log(pp(1))+log(pp(2)))/2.) ! initialization, rectified with ps below |
---|
| 124 | else |
---|
| 125 | deltap(ilon,ilat,1,itim)= miss_val |
---|
| 126 | endif |
---|
| 127 | do ilev=2,altlength-1 |
---|
| 128 | deltap(ilon,ilat,ilev,itim)= exp((log(pp(ilev-1))+log(pp(ilev)))/2.)-& |
---|
| 129 | exp((log(pp(ilev))+log(pp(ilev+1)))/2.) |
---|
| 130 | enddo |
---|
| 131 | deltap(ilon,ilat,altlength,itim)=exp((log(pp(altlength-1))+log(pp(altlength)))/2.) |
---|
| 132 | enddo |
---|
| 133 | enddo |
---|
| 134 | |
---|
| 135 | do ilon=1,lonlength |
---|
| 136 | do ilat=1,latlength |
---|
| 137 | tmpp=ps(ilon,ilat,itim) |
---|
| 138 | pp=press(ilon,ilat,:,itim) |
---|
| 139 | do ilev=altlength,2,-1 |
---|
| 140 | if ((pp(ilev).le.tmpp).and.(pp(ilev-1).gt.tmpp)) then |
---|
| 141 | deltap(ilon,ilat,ilev,itim)= tmpp - & |
---|
| 142 | exp((log(pp(ilev))+log(pp(ilev+1)))/2.) |
---|
| 143 | elseif (pp(ilev).gt.tmpp) then |
---|
| 144 | deltap(ilon,ilat,ilev,itim)=miss_val |
---|
| 145 | endif |
---|
| 146 | enddo |
---|
| 147 | enddo |
---|
| 148 | enddo |
---|
| 149 | |
---|
| 150 | enddo ! timelength |
---|
| 151 | |
---|
| 152 | !=============================================================================== |
---|
| 153 | ! 2.2.2 Mass in cells |
---|
| 154 | !=============================================================================== |
---|
| 155 | |
---|
| 156 | do itim=1,timelength |
---|
| 157 | |
---|
| 158 | do ilon=1,lonlength |
---|
| 159 | do ilat=1,latlength |
---|
| 160 | do ilev=1,altlength |
---|
| 161 | if ((deltap(ilon,ilat,ilev,itim).ne.miss_val) & |
---|
| 162 | .and. (rayon(ilon,ilat,ilev,itim).ne.miss_val) & |
---|
| 163 | .and. (grav(ilon,ilat,ilev,itim).ne.miss_val)) then |
---|
| 164 | dmass(ilon,ilat,ilev,itim) = & |
---|
| 165 | rayon(ilon,ilat,ilev,itim)*cos(latrad(ilat))*deltalon & |
---|
| 166 | * rayon(ilon,ilat,ilev,itim)*deltalat & |
---|
| 167 | * deltap(ilon,ilat,ilev,itim)/grav(ilon,ilat,ilev,itim) |
---|
| 168 | else |
---|
| 169 | dmass(ilon,ilat,ilev,itim) = miss_val |
---|
| 170 | endif |
---|
| 171 | enddo |
---|
| 172 | enddo |
---|
| 173 | enddo |
---|
| 174 | |
---|
| 175 | enddo ! timelength |
---|
| 176 | |
---|
| 177 | end subroutine cellmass |
---|