#include <misc.h>
#include <preproc.h>
#ifndef COUP_CSM
      subroutine lsmini (londim  ,beglatatm ,endlatatm ,
     &                   nlonatm ,oroatm    ,xmdbase   ,xmsbase   ,
     &                   xmbdate ,xmbsec    ,xnstep    ,dtatm     ,
     &                   xnsrest ,xnestep   ,xnhtfrq   ,xmfilt    , 
     &                   xirt      ,xirad     ,lwupxy    ,
     &                   tsxy    ,asdirxy   ,asdifxy   ,aldirxy   ,
     &                   aldifxy ,snowxy    ,eccen     ,obliqr    ,
     &                   lambm0  ,mvelpp    ,xcaseid   ,xinithist ,
     &                   xctitle   ,xnswrps   )
#else
      subroutine lsmini (eccen   ,obliqr  ,lambm0   ,mvelpp ) 
#endif

! ------------------------ code history --------------------------------
! source file:       lsmini.F
! purpose:           lsm initialization. return land surface variables to
!                    atm model if initial run
! date last revised: August 1996 - lsm version 1
! author:            Gordon Bonan
! standardized:      
! reviewed:         
!
! $Id: lsmini.F,v 1.27 2000/05/17 19:20:49 rosinski Exp $
! ----------------------------------------------------------------------

! ------------------------ notes ---------------------------------------
! initialization routine for land surface model. 
!
! the land surface model works by gathering all the land points on a
! [lsmlon] x [lsmlat] grid into a vector of [lpt] land points. this is
! then expanded into a "big" vector of [kpt] subgrid points, allowing for
! up to [msub] subgrid points per land point. the [kpt] subgrid points
! are processed as [numlv] "little" vectors of [numkpt] points for [numlv] 
! calls to the vector-based land surface model. 
!
! model constants are set in block data subprograms. this subroutine: 
!   o determines time-invariant surface data on [lsmlon] x [lsmlat] grid 
!     if initial run with arbitrary initialization this dataset is
!     created at run time, otherwise it is obtained from the initial 
!     or restart dataset
!   o initializes run control variables for 
!     common blocks via the [lsmexp] namelist 
!   o defines the multiple plant types and fraction areas for each surface type 
!   o builds the appropriate subgrid <-> grid mapping indices  
!   o assigns subgrid points the appropriate time-invariant data. i.e., 
!     initializes the time constant [lsmtc] common block
!
! for an initial run only:
!   o reads initial data 
!   o returns required land surface variables to atm model (coupled to ccm)
!   o initializes history file variables
!   o reads restart data if a continuation run 
!
! if run is coupled to ccm, then this grid (size, lat and lon indexing) 
! must be the same as the atmospheric grid. this constraint no longer 
! holds if the land model runs as a separate executable through the 
! flux coupler. a brief description follows:
! if initial run:
!  o if arbitrary initialization the surface dataset is calculated
!    and is written out as diagnostic output (see below)
!  o if the run is initiated from an initial dataset, the dataset is
!    opened and read
! if restart or branch run:
!  o get appropriate restart and history file names if continuation run. 
!  o restart: the file lsmr_rstrt contains the full mass store or 
!    local names of the current restart file history file, lsmh_xxxx.
!  o branch: the variable nrevsn is the full mass store or local name
!    of the appropriate restart file. Will open a new history file 
!    starting with lsmh_0001.
! ----------------------------------------------------------------------

      use precision
      use lsmpar
      use lsmvar
      use hist_timvar
      use hist_timcon
      use histvars
#if ( defined SPMD )
      use mpishorthand
      use lsm_spmd
#endif
      use basin
      implicit none
#include <lsmctl.h>
 
! ------------------------ input/output variables ----------------------
#if (!defined COUP_CSM )

! input from atmospheric model
      integer londim            !num of atm longitude points
      integer beglatatm         !beg lat on proc, degenerates to 1      for nonspmd
      integer endlatatm         !end lat on proc, degenerates to lsmlat for nonspmd
      integer nlonatm(*)        !number of longitudes per latitude band from atm
      integer xmdbase           !base day of run (e.g., 0)
      integer xmsbase           !base seconds of base day (e.g., 0)
      integer xmbdate           !base date of run (yymmdd format) (e.g., 000901)
      integer xmbsec            !base seconds of base date (e.g., 0)
      integer xnstep            !time step index
      integer xnestep           !ending time step index
      integer xnhtfrq           !history interval(iterations)
      integer xmfilt            !max number of time samples per history file
      integer xirad             !solar radiation frequency (iterations)
      integer xirt              !mss retention time
      integer xnsrest           !0 = initial run, > 0 = continuation run
      character*17 xcaseid      !case id
      character*80 xctitle      !case title 
      character*8 xnswrps       !mss password
      character*8 xinithist     !write frequency for lsm initial datasets
      real(r8) dtatm                                 !time step (s)
      real(r8) oroatm(londim,beglatatm:endlatatm)    !oro flag from atm: 0=non-land 1=land 

! output to atmospheric model
      real(r8) asdirxy(londim,beglatatm:endlatatm)   !albedo - visible waveband, direct
      real(r8) asdifxy(londim,beglatatm:endlatatm)   !albedo - visible waveband, diffuse
      real(r8) aldirxy(londim,beglatatm:endlatatm)   !albedo - near infrared waveband, direct
      real(r8) aldifxy(londim,beglatatm:endlatatm)   !albedo - near infrared waveband, diffuse
      real(r8) tsxy   (londim,beglatatm:endlatatm)   !surface (skin) temperature
      real(r8) lwupxy (londim,beglatatm:endlatatm)   !emitted longwave radiation (w/m**2)
      real(r8) snowxy (londim,beglatatm:endlatatm)   !water equivalent snow (m)

#endif

      real(r8) eccen            !Earth's orbital eccentricity
      real(r8) obliqr           !Earth's obliquity in radians
      real(r8) lambm0           !Mean longitude of perihelion at the vernal
                                !equinox (radians)
      real(r8) mvelpp           !Earth's moving vernal equinox longitude of 
                                !perihelion plus pi (radians)

! ----------------------------------------------------------------------

! ------------------------ local variables -----------------------------
      integer i            !indices
      integer kyr          !current year (0, ...)
      integer kmo          !current month (1 -> 12)
      integer kda          !current day (1 -> 31)

      real(r8) calday      !current gmt calendar day (1.00 -> 365.00)
! ----------------------------------------------------------------------

! ----------------------------------------------------------------------
! set lsmpar module variables
! ----------------------------------------------------------------------

#if (!defined COUP_CSM)
      beglat = beglatatm
      endlat = endlatatm
#if (defined SPMD)
      call lsm_ccmspmd()
#endif
#endif

#if (!defined SPMD)
      masterproc = .true.
#endif

! ----------------------------------------------------------------------
! write log output
! ----------------------------------------------------------------------
 
      write (6,*)
      write (6,*) '************************************************'
      write (6,*) 'LSM land surface model, version 1.0'
      write (6,*) 'This model is described in full by: Bonan, G.B. ',
     &     '1996. A land surface model'
      write (6,*) '(LSM version 1.0) for ecological, hydrological, ',
     &     'and atmospheric studies:'
      write (6,*) 'technical description and users guide. NCAR ',
     &     'Technical Note NCAR/TN-417+STR.'
      write (6,*) 'National Center for Atmospheric Research, ',
     &     'Boulder, Colorado.'
      write (6,*)
      write (6,*) 'attempting to initialize LSM'
      write (6,*)

! ----------------------------------------------------------------------
! initialize run control variables
! ----------------------------------------------------------------------

#ifdef COUP_CSM
      call lsmctli
#else
      call lsmctli (xmdbase, xmsbase, xmbdate  , xmbsec,
     &              xnsrest, xnstep , xnestep  , dtatm ,
     &              xnhtfrq, xmfilt , xirt  ,
     &              xirad  , xcaseid, xinithist, xctitle,
     $              xnswrps)
#endif

! ----------------------------------------------------------------------
! initialize fortran unit numbers 1 to 99 to inactive: except standard 
! input (5) and standard output (6) 
! ----------------------------------------------------------------------

      do i = 1, 99
         lsmiou(i) = .false.
      end do
      lsmiou(5) = .true.
      lsmiou(6) = .true.

      write (6,*) 'preset fortran unit numbers:'
      write (6,*) '   unit  5 = standard input'
      write (6,*) '   unit  6 = standard output'
      write (6,*)

! ----------------------------------------------------------------------
! set mass store pathnames for history and restart files
! ----------------------------------------------------------------------

      call msspni

! ----------------------------------------------------------------------
! determine initial or restart data
! ----------------------------------------------------------------------

#ifdef COUP_CSM
      if (nsrest.eq.0  .and. finidat.eq.'arbitrary initialization') then
         call lsmcrarbi
      else if (nsrest.eq.0 ) then  
         call lsmrdinit
      else
         call lsmrdrest
      endif	
#else
      if (nsrest.eq.0  .and. finidat.eq.'arbitrary initialization') then
         call lsmcrarbi(londim, oroatm, nlonatm)
      else if (nsrest.eq.0 ) then  
         call lsmrdinit(londim, oroatm)
      else
         call lsmrdrest(londim, oroatm)
      endif
#endif
      
! ----------------------------------------------------------------------
! if initial or branch run, write time constant history file 
! ----------------------------------------------------------------------

      if (nsrest.eq.0 .or. nsrest.eq.3) then
         call histtc
      endif

! ----------------------------------------------------------------------
! initialize variables for history files
! ----------------------------------------------------------------------

      call histini (nsrest)

! ----------------------------------------------------------------------
! determine calendar information for current time step
! ----------------------------------------------------------------------

      call calendr(nbstep  ,dtlsm  ,mdbase  ,msbase  ,mbdate  ,
     &             mbsec   ,mdcur  ,mscur   ,mcdate  ,mcsec   ,
     &             calday  )

      kyr = mcdate/10000
      kmo = mod(mcdate,10000)/100
      kda = mod(mcdate,100)

! for monthly averaged history tapes, the following variables
! must be initialized here if the initial run is not started from 
! the beginning of the month. if the run is started at the beginning 
! of the month, then the values are overwritten in routine histend.

      if (nhtfrq == 0 .and. nsrest == 0) then 
         nmon     = kmo           
         nyr      = kyr            
         mcdate_f = mcdate
         mcsec_f  = mcsec
         mdcur_f  = mdcur
         mscur_f  = mscur
      endif

! ----------------------------------------------------------------------
! if initial run initialize [tvdyn] common block and surface 
! variables for atmospheric model.
! note that if continuation or branch run, time-varying data in 
! [tvdyn] common block has been read in by lsm in subroutine lsmrdrest. 
! (also note that atmospheric model has albedos, upward longwave flux, 
! etc. in its own restart file).
! ----------------------------------------------------------------------

      if (nsrest .eq. 0) then
 
! initialize time-varying data in [tvdyn] common block 

         call lsmtvi (calday   ,eccen    ,obliqr  ,lambm0   ,
     $                mvelpp   ,nbstep   ,kmo     ,kda)
      
#if (!defined COUP_CSM) 
! return surface variables for atmospheric model

         call atmini (londim ,lwupxy, tsxy, asdirxy, asdifxy,
     $                aldirxy, aldifxy, snowxy)

#endif

      endif

! ----------------------------------------------------------------------
! initialize basin runoff
! ----------------------------------------------------------------------

      call basinini

! ----------------------------------------------------------------------
! end lsm initialization
! ----------------------------------------------------------------------

      write (6,*) ('successful initialization of LSM')
      if (nsrest .eq. 0) then
         write (6,*) 'begin initial run at:'
      else
         write (6,*) 'begin continuation run at:'
      end if
      write (6,*) '   nstep= ',nbstep,' year= ',kyr,' month= ',kmo,
     &     ' day= ',kda,' seconds= ',mscur
      write (6,*)
      write (6,*) '************************************************'
      write (6,*)

      return
      end
 
