  subroutine psd_create_all(idst, imax, stype, nbins, diam_cut, d0, dd, psd_m, dpsd_m, psd_f, dpsd_f, ibin_u, ibin_l)
  
!-----------------------------------------------------------------------------------
! Calculate minimally- and fully-dispersed particle-size distributions for use with 
! dust emission schemes.
!
! M. Klose, 2017
!-----------------------------------------------------------------------------------  
  
  implicit none 
  
  integer, intent(in)                   :: imax               ! 60, No. of particle size intervals for psd
  integer, intent(in)                   :: stype              ! 12, No. of soil texture classes
  integer, intent(in)                   :: nbins              ! 8, No. of dust transport bins
  real,    intent(in), dimension(nbins) :: diam_cut           ! upper diameter limits of dust transport bins
!   
  integer, intent(out) :: idst
  integer, dimension(nbins),      intent(out) :: ibin_u, ibin_l   ! indices in psds for upper and lower bin limits  
  real,    dimension(0:imax),     intent(out) :: d0  
  real,    dimension(imax),       intent(out) :: dd   
  real,    dimension(imax,stype), intent(out) :: psd_m, dpsd_m !, ppsd_m
  real,    dimension(imax,stype), intent(out) :: psd_f, dpsd_f !, ppsd_f
!   real, parameter :: dcut=20.d0             ! dust cutoff particle size  
  
! local variables
  
  integer            :: p, n, ind!, i
  integer, parameter :: jmax=4                 ! No. of log-normal distributions for constructing psd  
!  integer, parameter :: stype=12               ! No. of soil texture classes  
  real, dimension(imax) :: psdm, dpsdm, ppsdm
  real, dimension(imax) :: psdf, dpsdf, ppsdf  
!  character*4, dimension(12) :: s_type
!  data s_type / 'sand', 'losa', 'salo', 'silo', 'silt', 'loam', 'sclo', 'sico', 'cllo', & 
!  &             'sacl', 'sicl', 'clay' /
!-----------------------------------------------------------------------------------
  include 'soilpsd_coef.inc'
!-----------------------------------------------------------------------------------
   write(*,*) 'calculate particle-size distributions'
   psd_m(:,:) = 0.
   psd_f(:,:) = 0.
   dpsd_m(:,:) = 0.
   dpsd_f(:,:) = 0. 

   do p = 1, stype
      if (p.eq.1) then            ! sand
         call psd_create(d0, dd, psdm, dpsdm, imax, csandm, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csandf, jmax)
      elseif (p.eq.2) then        ! loamy sand
         call psd_create(d0, dd, psdm, dpsdm, imax, closam, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, closaf, jmax)
      elseif (p.eq.3) then        ! sandy loam
         call psd_create(d0, dd, psdm, dpsdm, imax, csalom, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csalof, jmax)
      elseif (p.eq.4) then        ! silt loam
         call psd_create(d0, dd, psdm, dpsdm, imax, csilom, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csilof, jmax)
      elseif (p.eq.5) then        ! silt
         call psd_create(d0, dd, psdm, dpsdm, imax, csiltm, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csiltf, jmax)
      elseif (p.eq.6) then        ! loam
         call psd_create(d0, dd, psdm, dpsdm, imax, cloamm, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, cloamf, jmax)
      elseif (p.eq.7) then        ! sandy clay loam
         call psd_create(d0, dd, psdm, dpsdm, imax, csclom, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csclof, jmax)
      elseif (p.eq.8) then        ! silty clay loam
         call psd_create(d0, dd, psdm, dpsdm, imax, csiclm, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csiclf, jmax)
      elseif (p.eq.9) then        ! clay loam
         call psd_create(d0, dd, psdm, dpsdm, imax, ccloam, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, ccloaf, jmax)
      elseif (p.eq.10) then        ! sandy clay
         call psd_create(d0, dd, psdm, dpsdm, imax, csaclm, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csaclf, jmax)
      elseif (p.eq.11) then        ! silty clay
         call psd_create(d0, dd, psdm, dpsdm, imax, csilcm, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, csilcf, jmax)         
      elseif (p.eq.12) then        ! clay
         call psd_create(d0, dd, psdm, dpsdm, imax, cclaym, jmax)
         call psd_create(d0, dd, psdf, dpsdf, imax, cclayf, jmax)       
      endif
!          open(11, file='psd_EASI_60bins_'//s_type(p)//'.txt')
!          do i= 1, imax
!             write(11, *) dd(i), psdm(i), psdf(i), dpsdm(i), dpsdf(i) 
!          enddo
!          close(11)
      psd_m(:,p) = psdm(:)
      psd_f(:,p) = psdf(:)
      dpsd_m(:,p) = dpsdm(:)
      dpsd_f(:,p) = dpsdf(:)
  
   enddo
   
!  find maximum index in psd that corresponds to a particle-size below 20 microns. 
   ind = imax   ! don't reset ind for each loop - ind continuously decreases
   DO n = nbins, 1, -1
      DO WHILE (d0(ind) .gt. diam_cut(n)) 
         ind = ind - 1
      ENDDO
      ibin_u(n) = ind
      IF (n .lt. nbins) THEN
         ibin_l(n+1) = ibin_u(n) + 1
      ENDIF
   ENDDO 
   ibin_l(1) = 1
   idst = ibin_u(nbins)
   
   END SUBROUTINE psd_create_all 
   
!--------------------------------------------------------------------------------
   SUBROUTINE psd_create(d, dm, psd, dpsd, imax, cmtrix, jmax)  
!--------------------------------------------------------------------------------
! Yaping Shao, 13 June 2000
!
! - Generate particle size distribution density function 
!   (both minimally-dispersed and fully-dispersed as the 
!   sum of four log-normal distributions.
!
! d(0,imax):    output, particle size at 0, 1, 2, ..., imax points    [um]
! dm(imax):     output, particle size at middle of 0-1, 1-2, etc      [um]
! psd(imax):    output, particle size distribution density at dm      [um^-1]
! dpsd(imax):   output, Delta P for sections 0-1, 1-2, etc.           [ ]
! ppsd(imax):   output, P for sections 0-1, 1-2, etc.                 [ ]
! imax:         input, length dm, psd, dpsdm, ppsd, etc.
! cmtrix:       jmaxx coefficient matrix 
!               e.g.
!               w1   = cmtrix(1, 1): weight for first log-normal distribution
!               dln1 = cmtrix(2, 1): mean log-particle size of first log-normal distribution 
!               sig1 = cmtrix(3, 1): sigma of log-particle size for first log-normal distribution
!               etc. 
!               careful with the dimension of dln and sig
!----------------------------------------------------------------------------
!
      integer, intent(in) :: imax
      integer :: i, j, jmax
      real, dimension(3, jmax) :: cmtrix
      real :: d(0:imax), dm(imax)                 
      real :: psd(imax), dpsd(imax), ppsd(imax)   ! for p(d), Delta P(d) and P(d)
      real :: p, pp, w, dln, sig
      real :: cn
      real, parameter :: eps=1.e-7
!      real, parameter :: dref=1000.
      real, parameter :: dref=2000., dphi=0.25
      real :: phi, phi0
!       real :: fu, fd, phi, phi0
!---------------------------------------------------------------------------
!
      cn = 1.0/sqrt(2.*3.14159)
!
! initialise psd, dpsd, ppsd
!
      psd = 0.0
      dpsd = 0.0
      ppsd = 0.0
! ! !
! ! ! Estimate d using phi scale. phi varies between from 9 to -1
! ! ! with increment 0.1. Reference particle size d0 = 1000 um
! ! !
! !       fu = 10.0
! !       fd = -1.0
! !       do i = 0, imax
! !          phi = fu - i*(fu-fd)/imax
! !          d(i) = dref/2.0**phi
! !       enddo 
! !       
! MKLOSE: Use quarter-phi scale with dref = 2000 now to better resolve the smallest particle sizes. 
!         This also reduces imax to 60 and starts from smaller particle diameters. 
!         Possible to change to half-phi scale with 30 bins and somewhat reduced accuracy. 
      if (imax.ne.60) write(0,*) 'WARNING: number of particle size bins seems to be wrong'
      phi0 = -log(dref)/log(2.)    ! This should be -log2(dref), which is log10(dref)/log10(2)
      do i = 0, imax
         phi = phi0 + (imax-i)*dphi
         d(i) = 2.**(-phi)
!          print*, d(i), phi
      enddo      
!
      do i = 1, imax
!          dm(i) = dexp( (dlog(d(i))+dlog(d(i-1)) )/2.d0 )   ! = sqrt(d(i)*d(i-1))
        dm(i) = (d(i)-d(i-1))/log(d(i)/d(i-1))               ! d = delta(d) / delta(log d), because del (log d) = (del d) / d   ! mklose [17122014]

        pp = 0.0
        do j = 1, jmax
           w = cmtrix(1, j)
           dln = cmtrix(2, j)
           sig = cmtrix(3, j)
           if ( (w.gt.eps) .and. (sig.ne.0.) ) then
              p = w*cn/sig*exp( -(log(dm(i))-dln)**2./(2.*sig**2.) )
           else
              p=0.0
          endif
          pp = pp + p
        enddo
!
        dpsd(i) = pp*( log(d(i)) - log(d(i-1)) )        ! Delta P over i
        if (i.eq.1) then 
           ppsd(i) = 0.0 + dpsd(i)                        ! P(d), with P(0) = 0
        else
           ppsd(i) = ppsd(i-1) + dpsd(i)      
        endif
        psd(i) = pp/dm(i)                                 ! p(d), particle size distribution density

      enddo
!
! Renormalisation, in case ppsd(imax) is not 1
!
      dpsd = dpsd/ppsd(imax)
      psd  = psd/ppsd(imax)
      ppsd = ppsd/ppsd(imax)
   
   END SUBROUTINE psd_create
