bri_tem_nonsnow.f90

来自「CLM集合卡曼滤波数据同化算法」· F90 代码 · 共 2,381 行 · 第 1/5 页

F90
2,381
字号
      common /p/pi,pi2,spi,spi2      common /al/cl,effslop,npol      common /qua/ zt,wt,npts      common /type/itype      external bessk,BesselK,alogam       real uth, cu, fu      common /order/uth,cu,fu      q = dsqrt( u*u + v*v )      go to (1,2,3,4), itype!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c! gaussian spectrum!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c 1      spectrum=cl*cl/(2.0*fn)*exp(-cl*cl*q*q/(4.0*fn))       go to 10!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c! exponential spectrum!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c 2      spectrum=(fn/cl)/((fn/cl)**2+q*q)**1.5      go to 10!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c! transformed exponential spectrum          c!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c3      continue      e = 1.5 * fn - 1.0d0      y = 1.5 * fn      gam = ( alogam(y) ) !gamma function (1.5n)      ql = q * cl       if ( ql .eq. 0.0d0 ) then         spectrum = cl*cl/(3.0*fn-2.0)       return      endif      if ( dmod( fn, 2.0d0) .eq. 0.0d0) then         m = 1.5 * fn - 1.0            !fn is even;         bk = log(BESSK( m, ql))           !integer order, check OK     else      m = 1.5 * fn - 1.0  - 0.5    !fn is odd      bk = log(BesselK( m, ql))          !fractional order      endif      out = cl * cl * ( ql / 2.0d0) ** e      spectrum=  out * dexp(bk - gam ) ! direct integration for valid checking on the above recursion eq.!         call bestran(funtexp,u,v,fn,out1)!         spectrum=out1      go to 104     continue      nf = fn      spectrum= powerlaw(q,cl,uth,nf,cu,fu)      go to 1010      return      end!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c! transfromed exponential correlation       c!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c      function funtexp(x,uv,fn)      implicit real*8 (a-h,k,o-z)      common /al/cl,effslop,npol!      funtexp=dexp(-fn*(x/cl)**1.2)*x*bessj0(uv*x)!      funtexp=dexp(-fn*x*x/cl/cl)*x*bessj0(uv*x)      funtexp=dexp(-fn*x*x/(1.8**4.0+x*x*3.0*3.0)**0.5)     &	          *x*bessj0(uv*x)      return      end!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c! this routine computes the surface spectrum        c! by directly doing the bessel transfrom of         c! the surface correlation function when no closed   c! forms are available                               c!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c      subroutine bestran(func,u,v,fn,result)      implicit real*8 (a-h,k,o-z)      dimension zt(512),z1(512),wt(512)      common /qua/zt,wt,npts      external func      epsilon =  1.0d0-1.0d-8      uv=dsqrt(u*u+v*v)      a1=0.0d0      b1=100.0d0      sum1=0.0d0      old=1.0d0      c=(b1-a1)/2.0      do 5 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.05     continue      do 10 j=1,npts       x=z1(j)       sum1=sum1+wt(j)*func(x,uv,fn)10    continue      a1=100.0d0      b1=200.0d0      sum2=0.0d0      c=(b1-a1)/2.0      do 15 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.015     continue      do 20 j=1,npts       x=z1(j)       sum2=sum2+wt(j)*func(x,uv,fn)20    continue        a1=200.0d0      b1=300.0d0      sum3=0.0d0      c=(b1-a1)/2.0      do 25 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.025     continue      do 30 j=1,npts       x=z1(j)       sum3=sum3+wt(j)*func(x,uv,fn)30    continue                a1=300.0d0      b1=400.0d0      sum4=0.0d0      c=(b1-a1)/2.0      do 35 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.035     continue      do 40 j=1,npts       x=z1(j)       sum4=sum4+wt(j)*func(x,uv,fn)40    continue           a1=400.0d0      b1=500.0d0      sum5=0.0d0      c=(b1-a1)/2.0      do 45 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.045     continue      do 50 j=1,npts       x=z1(j)       sum5=sum5+wt(j)*func(x,uv,fn)50    continue           a1=500.0d0      b1=600.0d0      sum6=0.0d0      c=(b1-a1)/2.0      do 55 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.055     continue      do 60 j=1,npts       x=z1(j)       sum6=sum6+wt(j)*func(x,uv,fn)60    continue        a1=600.0d0      b1=700.0d0      sum7=0.0d0      c=(b1-a1)/2.0      do 65 i=1,npts      z1(i)=c*zt(i)+(b1+a1)/2.065     continue      do 70 j=1,npts       x=z1(j)       sum7=sum7+wt(j)*func(x,uv,fn)70    continue        result=(sum1+sum2+sum3+sum4+sum5+sum6+sum7)*c      return      end      subroutine quagen(z,wt,n)           integer n      real*8 z(n),wt(n)      real*8 p(513),c1(513),c2(513)      real*8 pi,pi4,pdir,xnow,const,epsilon      logical found      data p(1),epsilon,nmax,ip /1.d0,1.d-10,10,512/      if(n.le.0.or.n.gt.ip) thenwrite(*,*) 'input order out of range'       stop      endif!!     calculate the coefficients for the legendre poly. recursive formula!         do 10 i=2,n      c1(i)=(2*i-1)/dfloat(i)      c2(i)=(i-1)/dfloat(i) 10   continue!!     initial constants!      n1=n+1      pi=acos(-1.d0)      pi4=pi/4      const=1.d0/(n+0.5)!!     determine the number of roots(nr) needed to be calculated!      n2=n/2      if(n2*2.eq.n) then       ncal=n2      else       ncal=n2+1      endif! !     main loop begins here!         do i=1,ncal       k=n-i+1       ncount=0       xinc=1.d0!!     use newton's method and a good initial guess to locate the root!       xnow=cos((i*pi-pi4)*const)       found=.false.      do while (.not.found)       ncount=ncount+1       p(2)=xnow!!     the following loop calculate p_n(x) using recursive formula!       do 20 j=2,n       p(j+1)=c1(j)*xnow*p(j)-c2(j)*p(j-1)  20    continue!!     the derivate of p_n(x) can be calculated from p_n(x) and p_n-1(x)!       pdir=n*(p(n)-xnow*p(n1))/(1.d0-xnow*xnow)      if(abs(xinc).le.epsilon.or.ncount.gt.nmax) then        found=.true.       z(k)=xnow       z(i)=-xnow       wt(k)=2.d0/(1.d0-z(k)*z(k))/(pdir*pdir)       wt(i)=wt(k)      endif      xinc=-p(n1)/pdir      xnow=xnow+xinc      enddo      enddo      return      end      function bessj0(x)      real*8 x,y,p1,p2,p3,p4,p5,q1,q2,q3,q4,q5,r1,r2,r3,r4,r5,r6,     &	  s1,s2,s3,s4,s5,s6,bessj0      data r1,r2,r3,r4,r5,r6/57568490574.d0,-13362590354.d0,     &	  651619640.7d0,-11214424.18d0,77392.33017d0,-184.9052456d0/,       &	  s1,s2,s3,s4,s5,s6/57568490411.d0,1029532985.d0,9494680.718d0,     &	  59272.64853d0,267.8532712d0,1.d0/      data p1,p2,p3,p4,p5/1.d0,-.1098628627d-2,.2734510407d-4,     &	  -.2073370639d-5,.2093887211d-6/,q1,q2,q3,q4,q5/-.1562499995d-1,     &	  .1430488765d-3,-.6911147651d-5,.7621095161d-6,-.934945152d-7/      if(abs(x).lt.8.)then      y=x**2      bessj0=(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))))     &	    /(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))      else      ax=abs(x)      z=8./ax      y=z**2      xx=ax-.785398164      bessj0=sqrt(.636619772/ax)*(cos(xx)*(p1+y*(p2+y*(p3+y*(p4+y     &	    *p5))))-z*sin(xx)*(q1+y*(q2+y*(q3+y*(q4+y*q5)))))      endif      return      end      subroutine shadowg(ti,ts,s,shfct)      implicit real*8 (a-h,o-z)!       if(ts.ge.ti) then!         arg=ts!         else!           arg=ti!        endif      arg=ti      if(arg.eq.0.0) then        shfct=1.0         return      endif       u=1.0/dtand(arg)       pi=acos(-1.0d0)       et=u/(sqrt(2.0)*s)       if(et.ge.20) then         shfct=1.0          return      endif       f1=dsqrt(2.0/pi)*s*dexp(-et*et)/u       f2=erfc(et)       f=(f1-f2)/2.0       shfct=1.0/(1.0+f)!      shfct=(1.0-0.5*erfc(et))/(1.0+f)       return       end!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c! subroutine calculates shadowing function     c! (Tsang et al 1985, pp.95                     c!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c      subroutine shadow(back,ti,ts,shfct)      implicit real*8 (a-h,o-z)      logical back      common /al/cl,effslop,npol      s=effslop      if(ti.eq.0.0.and.ts.eq.0.0) then        shfct=1.0        return      endif       if(ti.eq.0.0) then          ui=1.0d+30        else          ui=1.0/tand(ti)       endif       if(ts.eq.0.0) then          us=1.0d+30       else          us=1.0/tand(ts)       endif       pi=acos(-1.0d0)       eti=ui/(sqrt(2.0)*s)       ets=us/(sqrt(2.0)*s)             if(.not.back) then      f1i=sqrt(2.0/pi)*s/ui*exp(-eti*eti)       f1s=sqrt(2.0/pi)*s/us*exp(-ets*ets)       f2i=erfc(eti)       f2s=erfc(ets)       fi=(f1i-f2i)/2.0       fs=(f1s-f2s)/2.0       shfct=1.0/(1.0+fi+fs)       else       if(ts.ge.ti) then      f1s=sqrt(2.0/pi)*s/us*exp(-ets*ets)      f2s=erfc(ets)      fs=(f1s-f2s)/2.0      shfct=(1.0-0.5*f2s)/(1.0+fs)       else         f1i=sqrt(2.0/pi)*s/ui*exp(-eti*eti)         f2i=erfc(eti)         fi=(f1i-f2i)/2.0        shfct=(1.0-0.5*f2i)/(fi+1.0)       endif      endif      return       end      function erfc(x)      implicit real*8 (a-h,o-z)      if(x.lt.0.)then      erfc=1.+gammp(.5,x**2)      else      erfc=gammq(.5,x**2)      endif      return      end      function gammp(a,x)      implicit real*8 (a-h,o-z)      if(x.lt.0..or.a.le.0.) pause      if(x.lt.a+1.)then      call gser(gamser,a,x,gln)      gammp=gamser      else      call gcf(gammcf,a,x,gln)      gammp=1.-gammcf      endif      return      end      function gammq(a,x)      implicit real*8 (a-h,o-z)      if(x.lt.0..or.a.le.0.)pause      if(x.lt.a+1.)then      call gser(gamser,a,x,gln)      gammq=1.-gamser      else      call gcf(gammcf,a,x,gln)      gammq=gammcf      endif      return      end      subroutine gser(gamser,a,x,gln)      implicit real*8 (a-h,o-z)      parameter (itmax=100,eps=3.e-7)      gln=gammln(a)      if(x.le.0.)then      if(x.lt.0.)pause      gamser=0.      return      endif      ap=a      sum=1./a      del=sum      do 11 n=1,itmax      ap=ap+1.      del=del*x/ap      sum=sum+del      if(abs(del).lt.abs(sum)*eps)go to 111    continue      pause 'a too large, itmax too small'1     gamser=sum*exp(-x+a*log(x)-gln)      return      end      subroutine gcf(gammcf,a,x,gln)      implicit real*8 (a-h,o-z)      parameter (itmax=100,eps=3.e-7)      gln=gammln(a)      gold=0.0d0      a0=1.0d0      a1=x      b0=0.0d0      b1=1.0d0      fac=1.0d0      do 11 n=1,itmax      an=float(n)      ana=an-a      a0=(a1+a0*ana)*fac      b0=(b1+b0*ana)*fac      anf=an*fac      a1=x*a0+anf*a1      b1=x*b0+anf*b1      if(a1.ne.0.)then        fac=1.0d0/a1        g=b1*fac         if(dabs((g-gold)/g).lt.eps)go to 1        gold=g      endif11    continue      pause 'a too large, itmax too small'1     gammcf=dexp(-x+a*dlog(x)-gln)*g      return      end      function gammln(xx)      implicit real*8 (a-h,o-z)      dimension cof(6)      data cof,stp/76.18009173D0,-86.50532033D0,24.01409822D0, &         -1.231739516D0,.120858003D-2,-.536382D-5,2.50662827465D0/      data half,one,fpf/0.5D0,1.0D0,5.5D0/      x=xx-one      tmp=x+fpf      tmp=(x+half)*dlog(tmp)-tmp      ser=one       do 11 j=1,6      x=x+one      ser=ser+cof(j)/x11    continue      gammln=tmp+dlog(stp*ser)      return      end!!      function BesselK(n,x)!***************************************************!  Modified Bessel function of order n+0.5!!  Input parameters:!    n : integer part of order!    x : real parameter!!***************************************************      implicit real*8 (a - h, k, o - z)      if(x.eq.0.0d0) then      print*,'BesselK: Singularity encountered !'      return      endif      PI = 4.0d0*atan(1.0d0)      cons = dsqrt(PI/(2.0d0*x))      K0 = cons*exp(-x)      if(n.eq.0) then      BesselK = K0      return      endif      K1 = K0*(1.0d0+1.0d0/x)      if(n.eq.1) then       BesselK = K1       return      endif      K2 = K0*(1.0d0+3.0d0/x+3.0d0/x/x)      if(n.eq.2) then

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?