Changeset 878
- Timestamp:
- Feb 12, 2013, 12:26:32 PM (12 years ago)
- Location:
- trunk/LMDZ.GENERIC
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.GENERIC/README
r875 r878 901 901 - Added a keyword to enable ocean runoff in callphys.def (activerunoff) 902 902 903 == 12/02/2013 == JL 904 - Follows previous commit by Aymeric about bilinear interpolations: 905 - Extended to all existing continua 906 - generalized bilinearbig to work for various size inputs 907 - because N2 and H2O continua databases are smaller, improvement around 15% for 908 an earth case. 903 909 904 910 911 -
trunk/LMDZ.GENERIC/libf/phystd/bilinearbig.F90
r873 r878 1 subroutine bilinearbig( x_arr,y_arr,f2d_arr,x_in,y_in,f,a)1 subroutine bilinearbig(nX,nY,x_arr,y_arr,f2d_arr,x_in,y_in,f,ind) 2 2 3 3 ! Necessary for interpolation of continuum data … … 6 6 implicit none 7 7 8 integer nX,nY,i,j,a,b 9 parameter(nX=2428) 10 parameter(nY=10) 8 integer nX,nY,i,j,ind,b 11 9 12 10 real*8 x_in,y_in,x1,x2,y1,y2 … … 28 26 !! ... and actually calculations only need to be done once 29 27 !! --> Case 1 : we have not calculated yet 30 if ( a== -9999) then28 if ( ind == -9999) then 31 29 !1st check we're within the wavenumber range 32 30 if ((x.lt.x_arr(2)).or.(x.gt.x_arr(nX-2))) then 33 31 f=0.0D+0 34 a=-132 ind=-1 35 33 else 36 34 i=1 … … 40 38 i=i+1 41 39 x2=x_arr(i) 42 a=i-140 ind=i-1 43 41 end do 44 42 endif 45 43 !! --> case 2 : we already saw we are out of wavenumber range 46 else if ( a== -1) then44 else if ( ind == -1) then 47 45 f=0.0D+0 48 46 return 49 47 !! --> case 3 : we already determined a -- so we just proceed 50 48 else 51 x1=x_arr( a)52 x2=x_arr( a+1)49 x1=x_arr(ind) 50 x2=x_arr(ind+1) 53 51 endif 54 52 … … 74 72 endif 75 73 76 f11=f2d_arr( a,b)77 f21=f2d_arr( a+1,b)78 f12=f2d_arr( a,b+1)79 f22=f2d_arr( a+1,b+1)74 f11=f2d_arr(ind,b) 75 f21=f2d_arr(ind+1,b) 76 f12=f2d_arr(ind,b+1) 77 f22=f2d_arr(ind+1,b+1) 80 78 81 79 call bilinear(f,f11,f21,f12,f22,x,x1,x2,y,y1,y2) -
trunk/LMDZ.GENERIC/libf/phystd/interpolateH2H2.F90
r873 r878 1 subroutine interpolateH2H2(wn,temp,pres,abcoef,firstcall, a)1 subroutine interpolateH2H2(wn,temp,pres,abcoef,firstcall,ind) 2 2 3 3 !================================================================== … … 54 54 integer nres 55 55 56 integer a56 integer ind 57 57 58 58 if(temp.gt.400)then … … 109 109 endif 110 110 111 call bilinearbig( wn_arr,temp_arr,abs_arr,wn,temp,abcoef,a)111 call bilinearbig(nS,nT,wn_arr,temp_arr,abs_arr,wn,temp,abcoef,ind) 112 112 113 113 !print*,'the absorption is ',abcoef,' cm^5 molecule^-2' -
trunk/LMDZ.GENERIC/libf/phystd/interpolateH2He.F90
r873 r878 1 subroutine interpolateH2He(wn,temp,presH2,presHe,abcoef,firstcall, a)1 subroutine interpolateH2He(wn,temp,presH2,presHe,abcoef,firstcall,ind) 2 2 3 3 !================================================================== … … 56 56 integer nres 57 57 58 integer a58 integer ind 59 59 60 60 if(temp.gt.400)then … … 112 112 endif 113 113 114 call bilinearbig( wn_arr,temp_arr,abs_arr,wn,temp,abcoef,a)114 call bilinearbig(nS,nT,wn_arr,temp_arr,abs_arr,wn,temp,abcoef,ind) 115 115 116 116 !print*,'the absorption is ',abcoef,' cm^5 molecule^-2' -
trunk/LMDZ.GENERIC/libf/phystd/interpolateH2Ocont_CKD.F90
r716 r878 1 subroutine interpolateH2Ocont_CKD(wn,temp,presS,presF,abcoef,firstcall )1 subroutine interpolateH2Ocont_CKD(wn,temp,presS,presF,abcoef,firstcall,ind) 2 2 3 3 !================================================================== … … 40 40 double precision data_tmp(nT) 41 41 42 integer k 42 integer k,ind 43 43 logical firstcall 44 44 … … 129 129 print*,' H2O pressure ',presS,' Pa' 130 130 print*,' air pressure ',presF,' Pa' 131 132 endif 131 133 132 call bilinearH2Ocont(wn_arr,temp_arr,abs_arrS,wn,temp,abcoefS)133 134 call bilinearbig(nS,nT,wn_arr,temp_arr,abs_arrS,wn,temp,abcoefS,ind) 135 ! print*,'the self absorption is ',abcoefS,' cm^2 molecule^-1' 134 136 135 call bilinearH2Ocont(wn_arr,temp_arr,abs_arrF,wn,temp,abcoefF)136 137 call bilinearbig(nS,nT,wn_arr,temp_arr,abs_arrF,wn,temp,abcoefF,ind) 138 ! print*,'the foreign absorption is ',abcoefF,' cm^2 molecule^-1' 137 139 138 139 140 ! print*,'We have ',amagatS,' amagats of H2O vapour' 141 ! print*,'and ',amagatF,' amagats of air' 140 142 141 142 143 abcoef = abcoefS*amagatS + abcoefF*amagatF ! Eq. (15) in Clough (1989) 144 abcoef = abcoef*(presS/(presF+presS)) ! take H2O mixing ratio into account 143 145 ! abs coeffs are given per molecule of H2O 144 146 145 146 147 Nmolec = (presS+presF)/(kB*temp) ! assume ideal gas 148 ! print*,'Total number of molecules per m^3 is',Nmolec 147 149 148 149 150 150 abcoef = abcoef*Nmolec/(100.0**2) ! convert to m^-1 151 ! print*,'So the total absorption is ',abcoef,' m^-1' 152 ! print*,'And optical depth / km : ',1000.0*abcoef 151 153 154 155 if(wn.gt.500 .and. wn.lt.1400)then 156 elseif(wn.gt.2100 .and. wn.lt.3000)then 152 157 else 158 abcoef = 0.0 159 endif 153 160 154 call bilinearH2Ocont(wn_arr,temp_arr,abs_arrS,wn,temp,abcoefS)155 call bilinearH2Ocont(wn_arr,temp_arr,abs_arrF,wn,temp,abcoefF)161 ! unlike for Rayleigh scattering, we do not currently weight by the BB function 162 ! however our bands are normally thin, so this is no big deal. 156 163 157 abcoef = abcoefS*amagatS + abcoefF*amagatF158 abcoef = abcoef*(presS/(presF+presS))159 160 Nmolec = (presS+presF)/(kB*temp)161 abcoef = abcoef*Nmolec/(100.0**2)162 163 if(wn.gt.500 .and. wn.lt.1400)then164 elseif(wn.gt.2100 .and. wn.lt.3000)then165 else166 abcoef = 0.0167 endif168 169 ! unlike for Rayleigh scattering, we do not currently weight by the BB function170 ! however our bands are normally thin, so this is no big deal.171 172 endif173 164 174 165 return 175 166 end subroutine interpolateH2Ocont_CKD 176 167 177 178 !-------------------------------------------------------------------------179 subroutine bilinearH2Ocont(x_arr,y_arr,f2d_arr,x_in,y_in,f)180 ! Necessary for interpolation of continuum data181 182 implicit none183 184 integer nX,nY,i,j,a,b185 parameter(nX=1001)186 parameter(nY=11)187 188 real*8 x_in,y_in,x,y,x1,x2,y1,y2189 real*8 f,f11,f12,f21,f22,fA,fB190 real*8 x_arr(nX)191 real*8 y_arr(nY)192 real*8 f2d_arr(nX,nY)193 194 integer strlen195 character*100 label196 label='subroutine bilinear'197 198 x=x_in199 y=y_in200 201 ! 1st check we're within the wavenumber range202 if ((x.lt.x_arr(2)).or.(x.gt.x_arr(nX-2))) then203 f=0.0D+0204 return205 else206 207 ! in the x (wavenumber) direction 1st208 i=1209 10 if (i.lt.(nX+1)) then210 if (x_arr(i).gt.x) then211 x1=x_arr(i-1)212 x2=x_arr(i)213 a=i-1214 i=9999215 endif216 i=i+1217 goto 10218 endif219 endif220 221 if ((y.lt.y_arr(1)).or.(y.gt.y_arr(nY))) then222 write(*,*) 'Warning from bilinearH2Ocont:'223 write(*,*) 'Outside continuum temperature range!'224 if(y.lt.y_arr(1))then225 y=y_arr(1)+0.01226 endif227 if(y.gt.y_arr(nY))then228 y=y_arr(nY)-0.01229 endif230 else231 232 ! in the y (temperature) direction 2nd233 j=1234 20 if (j.lt.(nY+1)) then235 if (y_arr(j).gt.y) then236 y1=y_arr(j-1)237 y2=y_arr(j)238 b=j-1239 j=9999240 endif241 j=j+1242 goto 20243 endif244 endif245 246 f11=f2d_arr(a,b)247 f21=f2d_arr(a+1,b)248 f12=f2d_arr(a,b+1)249 f22=f2d_arr(a+1,b+1)250 251 ! 1st in x-direction252 fA=f11*(x2-x)/(x2-x1)+f21*(x-x1)/(x2-x1)253 fB=f12*(x2-x)/(x2-x1)+f22*(x-x1)/(x2-x1)254 255 ! then in y-direction256 f=fA*(y2-y)/(y2-y1)+fB*(y-y1)/(y2-y1)257 258 return259 end subroutine bilinearH2Ocont -
trunk/LMDZ.GENERIC/libf/phystd/interpolateN2N2.F90
r716 r878 1 subroutine interpolateN2N2(wn,temp,pres,abcoef,firstcall )1 subroutine interpolateN2N2(wn,temp,pres,abcoef,firstcall,ind) 2 2 3 3 !================================================================== … … 21 21 double precision temp ! temperature (Kelvin) 22 22 double precision pres ! pressure (Pascals) 23 integer :: ind 23 24 24 25 ! output … … 104 105 print*,' pressure ',pres,' Pa' 105 106 106 call bilinearN2N2(wn_arr,temp_arr,abs_arr,wn,temp,abcoef) 107 endif 108 call bilinearbig(nS,nT,wn_arr,temp_arr,abs_arr,wn,temp,abcoef,ind) 107 109 108 print*,'the absorption is ',abcoef,' cm^5 molecule^-2'109 print*,'or ',abcoef*losch**2,' cm^-1 amagat^-2'110 ! print*,'the absorption is ',abcoef,' cm^5 molecule^-2' 111 ! print*,'or ',abcoef*losch**2,' cm^-1 amagat^-2' 110 112 111 113 abcoef=abcoef*losch**2*100.0*amagat**2 ! convert to m^-1 114 ! abcoef=0. 112 115 113 print*,'We have ',amagat,' amagats of N2'114 print*,'So the absorption is ',abcoef,' m^-1'116 ! print*,'We have ',amagat,' amagats of N2' 117 ! print*,'So the absorption is ',abcoef,' m^-1' 115 118 116 else 119 ! unlike for Rayleigh scattering, we do not currently weight by the BB function 120 ! however our bands are normally thin, so this is no big deal. 117 121 118 call bilinearN2N2(wn_arr,temp_arr,abs_arr,wn,temp,abcoef)119 abcoef=abcoef*losch**2*100.0*amagat**2 ! convert to m^-1120 121 ! unlike for Rayleigh scattering, we do not currently weight by the BB function122 ! however our bands are normally thin, so this is no big deal.123 124 endif125 122 126 123 return 127 124 end subroutine interpolateN2N2 128 125 129 130 !-------------------------------------------------------------------------131 subroutine bilinearN2N2(x_arr,y_arr,f2d_arr,x_in,y_in,f)132 133 implicit none134 135 integer nX,nY,i,j,a,b136 parameter(nX=582)137 parameter(nY=10)138 139 real*8 x_in,y_in,x,y,x1,x2,y1,y2140 real*8 f,f11,f12,f21,f22,fA,fB141 real*8 x_arr(nX)142 real*8 y_arr(nY)143 real*8 f2d_arr(nX,nY)144 145 integer strlen146 character*100 label147 label='subroutine bilinear'148 149 x=x_in150 y=y_in151 152 ! 1st check we're within the wavenumber range153 if ((x.lt.x_arr(2)).or.(x.gt.x_arr(nX-2))) then154 f=0.0D+0155 return156 else157 158 ! in the x (wavenumber) direction 1st159 i=1160 10 if (i.lt.(nX+1)) then161 if (x_arr(i).gt.x) then162 x1=x_arr(i-1)163 x2=x_arr(i)164 a=i-1165 i=9999166 endif167 i=i+1168 goto 10169 endif170 endif171 172 if ((y.lt.y_arr(1)).or.(y.gt.y_arr(nY))) then173 write(*,*) 'Warning from bilinearN2N2:'174 write(*,*) 'Outside continuum temperature range!'175 if(y.lt.y_arr(1))then176 y=y_arr(1)+0.01177 endif178 if(y.gt.y_arr(nY))then179 y=y_arr(nY)-0.01180 endif181 else182 183 ! in the y (temperature) direction 2nd184 j=1185 20 if (j.lt.(nY+1)) then186 if (y_arr(j).gt.y) then187 y1=y_arr(j-1)188 y2=y_arr(j)189 b=j-1190 j=9999191 endif192 j=j+1193 goto 20194 endif195 endif196 197 f11=f2d_arr(a,b)198 f21=f2d_arr(a+1,b)199 f12=f2d_arr(a,b+1)200 f22=f2d_arr(a+1,b+1)201 202 call bilinear(f,f11,f21,f12,f22,x,x1,x2,y,y1,y2)203 204 return205 end subroutine bilinearN2N2 -
trunk/LMDZ.GENERIC/libf/phystd/optci.F90
r873 r878 92 92 !! AS: to save time in computing continuum (see bilinearbig) 93 93 IF (.not.ALLOCATED(indi)) THEN 94 ALLOCATE(indi(L_NSPECTI,ngasmx ))94 ALLOCATE(indi(L_NSPECTI,ngasmx,ngasmx)) 95 95 indi = -9999 ! this initial value means "to be calculated" 96 96 ENDIF … … 162 162 if(igas.eq.igas_N2)then 163 163 164 call interpolateN2N2(wn_cont,T_cont,p_cont,dtemp,.false.) 164 interm = indi(nw,igas,igas) 165 call interpolateN2N2(wn_cont,T_cont,p_cont,dtemp,.false.,interm) 166 indi(nw,igas,igas) = interm 165 167 166 168 elseif(igas.eq.igas_H2)then 167 169 168 170 ! first do self-induced absorption 169 interm = indi(nw,igas )171 interm = indi(nw,igas,igas) 170 172 call interpolateH2H2(wn_cont,T_cont,p_cont,dtemp,.false.,interm) 171 indi(nw,igas ) = interm173 indi(nw,igas,igas) = interm 172 174 173 175 ! then cross-interactions with other gases … … 176 178 dtempc = 0.0 177 179 if(jgas.eq.igas_N2)then 178 call interpolateN2H2(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.) 180 interm = indi(nw,igas,jgas) 181 call interpolateN2H2(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm) 182 indi(nw,igas,jgas) = interm 179 183 elseif(jgas.eq.igas_He)then 180 interm = indi(nw, jgas)184 interm = indi(nw,igas,jgas) 181 185 call interpolateH2He(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm) 182 indi(nw, jgas) = interm186 indi(nw,igas,jgas) = interm 183 187 endif 184 188 dtemp = dtemp + dtempc … … 191 195 call interpolateH2Ocont_PPC(wn_cont,T_cont,p_cont,p_air,dtemp,.false.) 192 196 else 193 call interpolateH2Ocont_CKD(wn_cont,T_cont,p_cont,p_air,dtemp,.false.) 197 interm = indi(nw,igas,igas) 198 call interpolateH2Ocont_CKD(wn_cont,T_cont,p_cont,p_air,dtemp,.false.,interm) 199 indi(nw,igas,igas) = interm 194 200 endif 195 201 -
trunk/LMDZ.GENERIC/libf/phystd/optcv.F90
r873 r878 87 87 !! AS: to save time in computing continuum (see bilinearbig) 88 88 IF (.not.ALLOCATED(indv)) THEN 89 ALLOCATE(indv(L_NSPECTV,ngasmx ))89 ALLOCATE(indv(L_NSPECTV,ngasmx,ngasmx)) 90 90 indv = -9999 ! this initial value means "to be calculated" 91 91 ENDIF … … 157 157 if(igas.eq.igas_N2)then 158 158 159 !call interpolateN2N2(wn_cont,T_cont,p_cont,dtemp,.false.) 159 interm = indv(nw,igas,igas) 160 ! call interpolateN2N2(wn_cont,T_cont,p_cont,dtemp,.false.,interm) 161 indv(nw,igas,igas) = interm 160 162 ! only goes to 500 cm^-1, so unless we're around a cold brown dwarf, this is irrelevant in the visible 161 163 … … 163 165 164 166 ! first do self-induced absorption 165 interm = indv(nw,igas )167 interm = indv(nw,igas,igas) 166 168 call interpolateH2H2(wn_cont,T_cont,p_cont,dtemp,.false.,interm) 167 indv(nw,igas ) = interm169 indv(nw,igas,igas) = interm 168 170 169 171 ! then cross-interactions with other gases … … 172 174 dtempc = 0.0 173 175 if(jgas.eq.igas_N2)then 174 call interpolateN2H2(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.) 176 interm = indv(nw,igas,jgas) 177 call interpolateN2H2(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm) 178 indv(nw,igas,jgas) = interm 175 179 ! should be irrelevant in the visible 176 180 elseif(jgas.eq.igas_He)then 177 interm = indv(nw, jgas)181 interm = indv(nw,igas,jgas) 178 182 call interpolateH2He(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm) 179 indv(nw, jgas) = interm183 indv(nw,igas,jgas) = interm 180 184 endif 181 185 dtemp = dtemp + dtempc … … 188 192 call interpolateH2Ocont_PPC(wn_cont,T_cont,p_cont,p_air,dtemp,.false.) 189 193 else 190 call interpolateH2Ocont_CKD(wn_cont,T_cont,p_cont,p_air,dtemp,.false.) 194 interm = indv(nw,igas,igas) 195 call interpolateH2Ocont_CKD(wn_cont,T_cont,p_cont,p_air,dtemp,.false.,interm) 196 indv(nw,igas,igas) = interm 191 197 endif 192 198 -
trunk/LMDZ.GENERIC/libf/phystd/radcommon_h.F90
r873 r878 67 67 68 68 !! AS: introduced to avoid doing same computations again for continuum 69 INTEGER, DIMENSION(:,: ), ALLOCATABLE :: indi70 INTEGER, DIMENSION(:,: ), ALLOCATABLE :: indv69 INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: indi 70 INTEGER, DIMENSION(:,:,:), ALLOCATABLE :: indv 71 71 72 72 !!! ALLOCATABLE STUFF SO THAT DIMENSIONS ARE READ in *.dat FILES -- AS 12/2011
Note: See TracChangeset
for help on using the changeset viewer.