/* -------------------------------------------------------------
   channel_grid_flowlength
   returns the flowlength along a road surface in a channel
   if there is more than one road in a grid cell, the road
   with the greatest surface area is used to calculate the
   flowlength.
   This can result in a flolen that is greater than the
   horizontal length of the road in the cell.
  ------------------------------------------------------------- */


/* -------------------------------------------------------------
   channel_grid_flowslope
   returns the flowlength along a road surface in a grid cell
   if there is more than one road in a grid cell, the road
   with the greatest surface area is used to calculate the
   flowslope
   ------------------------------------------------------------- */


/* -------------------------------------------------------------
   channel_grid_class
   returns the erodibility coeffienct of the road surface in a
   gird cell. if there is more than one road in a grid cell, the road
   with the greatest surface area is used
   ------------------------------------------------------------- */


/*****************************************************************************
   Function name: SolarDay()

   Purpose:	 This subroutine calculates daily solar values

   Required:
    int DayOfYear	  - day of year (January 1 is 1)
    float Longitude        - site longitude (rad)
    float Latitude         - site latitude (rad)
    float StandardMeridian - longitude of time zone of standard meridian (rad)

   Returns: void

   Modifies:
     float *NoonHour       - true solar noon (hr)
     float *Declination    - solar Declination (rad)
     float *HalfDayLength  - half-day length (hr)
     float *Sunrise        - time of Sunrise (hr)
     float *Sunset         - time of Sunset (hr)
     float *TimeAdjustment - required adjustment to local time (hr)
     float *SunEarthDist   - distance from sun to earth

   Comments     : EXECUTE AT START OF EACH DAY
 *****************************************************************************/


/*****************************************************************************
  Function name: SolarHour()

  Purpose: This subroutine calculates position of the sun as a function of
           the time of day, the length of time the sun is above the horizon,
           and the maximum radiation.

  Required:
    float Latitude		- site laditude (rad)
    float LocalHour		- local time (hr)
    float Dt			- length of current timestep (hr)
    float NoonHour		- true solar noon (hr)
    float Declination		- solar Declination (rad)
    float Sunrise		- time of Sunrise (hr)
    float Sunset		- time of Sunset (hr)
    float TimeAdjustment	- required adjustment to convert local time
                  to solar time (hr)
    float SunEarthDist          - distance from Sun to Earth

  Returns: void

  Modifies:
    float *SineSolarAltitude - sine of sun's SolarAltitude
    int *DayLight	     - FALSE: measured solar radiation and the sun is
                                      below the horizon.
                   TRUE: sun is above the horizon
    float *SolarTimeStep     - fraction of the timestep the sun is above the
                               horizon
    float *SunMax            - calculated solar radiation at the top of the
                               atmosphere (W/m^2)

  Comments     : EXECUTE AT START OF EACH TIMESTEP
*****************************************************************************/


/* -------------------------------------------------------------
   SPrintDate
   Formats a DATE to a string
   ------------------------------------------------------------- */


/*****************************************************************************
  Function name: SizeOfNumberType()

  Purpose      : Determines the size of each number type.  Number type
                 descriptors are "borrowed" from HDF.

  Required     :
    NumberType - descriptor of number type (for more info see comments in
                 InitFileIO.c)

  Returns      : size of number type

  Modifies     : NA

  Comments     :
   Information about the number type has to be passed to the functions that
   deal with 2DMatrix and 2DSlab.  The following number types are recognized
   (they are adopted from the HDF standard):
   - NT_UINT8
     NT_UCHAR8:   8 bit unsigned int (i.e. unsigned char)
   - NT_UINT16:  16 bit unsigned int (i.e. unsigned short on most machines)
   - NT_UINT32:  32 bit unsigned int (i.e. unsigned int on most machines)
   - NT_INT8
     NT_CHAR8:    8 bit int (i.e. char)
   - NT_INT16:   16 bit int (i.e. short on most machines)
   - NT_INT32:   32 bit int (i.e. int on most machines)
   - NT_FLOAT32: 32 bit float (i.e. float on most machines)
   - NT_FLOAT64: 64 bit float (i.e. double on most machines)
*****************************************************************************/


/*****************************************************************************
  Function name: MakeFileNameGen()

  Purpose      : Generic file name generator, called by format specific file
                 name generating functions

  Required     :
    Path     - directory where file will be created
    Str1     - first part of file name
    Str2     - second part of file name
    Str3     - third part of file name
    FileName - new file name

  Returns      : void

  Modifies     : FileName

  Comments     : Str3 is intended to be used as an extension indicating the
                 file format , e.g. ".bin" or ".hdf"
*****************************************************************************/


/*****************************************************************************
  StoreModelState()

  Store the current state of the model.

  The state variables for DHSVM include the following variables:

    - Canopy interception for each vegetation layer

    - Snow pack conditions:
      - presence/absence
      - number of days since last snowfall (used in albedo calculation)
      - snow water equivalent
      - for each layer of the snow pack:
        - liquid water content
        - temperature
      - cold content

    - Soil conditions:
      - for each soil layer:
        - soil moisture (also for the layer below the deepest root zone)
        - temperature
      - surface temperature
      - ground heat storage
*****************************************************************************/


/*****************************************************************************
  Function: ReverseFloatMatrix()
  Usage: Revert the matrix Array2 by 180 degrees
  Author: Ning, 1/31/2013
******************************************************************************/


/*****************************************************************************
  Function name: SizeOfNumberType()

  Purpose      : Determines the size of each number type.  Number type
                 descriptors are "borrowed" from NetCDF.

  Required     :
    NumberType - descriptor of number type (for more info see comments in
                 InitFileIO.c)

  Returns      : size of number type

  Modifies     : NA

  Comments     :
   Information about the number type has to be passed to the functions that
   deal with 2DMatrix.  The number types are adopted from the NetCDF standard.
*****************************************************************************/


/*****************************************************************************
  Function name: SolarDay()

  Purpose:	 This subroutine calculates daily solar values

  Required:
   int DayOfYear	  - day of year (January 1 is 1)
   float Longitude        - site longitude (rad)
   float Latitude         - site latitude (rad)
   float StandardMeridian - longitude of time zone of standard meridian (rad)

  Returns: void

  Modifies:
    float *NoonHour       - true solar noon (hr)
    float *Declination    - solar Declination (rad)
    float *HalfDayLength  - half-day length (hr)
    float *Sunrise        - time of Sunrise (hr)
    float *Sunset         - time of Sunset (hr)
    float *TimeAdjustment - required adjustment to local time (hr)
    float *SunEarthDist   - distance from sun to earth

  Comments     : EXECUTE AT START OF EACH DAY
*****************************************************************************/


/*****************************************************************************
  Function name: SolarHour()

  Purpose: This subroutine calculates position of the sun as a function of
           the time of day, the length of time the sun is above the horizon,
           and the maximum radiation.

  Required:
    float Latitude		- site laditude (rad)
    float LocalHour		- local time (hr)
    float Dt			- length of current timestep (hr)
    float NoonHour		- true solar noon (hr)
    float Declination		- solar Declination (rad)
    float Sunrise		- time of Sunrise (hr)
    float Sunset		- time of Sunset (hr)
    float TimeAdjustment	- required adjustment to convert local time
				  to solar time (hr)
    float SunEarthDist          - distance from Sun to Earth

  Returns: void

  Modifies:
    float *SineSolarAltitude - sine of sun's SolarAltitude
    int *DayLight	     - FALSE: measured solar radiation and the sun is
                                      below the horizon.
			       TRUE: sun is above the horizon
    float *SolarTimeStep     - fraction of the timestep the sun is above the
                               horizon
    float *SunMax            - calculated solar radiation at the top of the
                               atmosphere (W/m^2)

  Comments     : EXECUTE AT START OF EACH TIMESTEP
*****************************************************************************/


/*#####################################################################################
 This function is used to find the matching key word in the input file for the "key"
 specified in the fucntion: InitVegTable( )
 #####################################################################################*/


/*****************************************************************************
  Function name: MakeFileNameNetCDF()

  Purpose      : Create a new file name ending in extension ".nc" to
                 indicate that the file is binary

  Required     :
    Path     - directory for files
    Str1     - first part of filename
    Str2     - second part of filename
    FileName - filename

  Returns      : void

  Modifies     : FileName

  Comments     :
*****************************************************************************/


/*******************************************************************************
  Function name: nc_check_err()

  Purpose      : Check status returned by NetCDF functions.

  Required     : int ncstatus - error status returned by NetCDF functions

  Returns      : void

  Modifies     : void

  Comments     :
*******************************************************************************/


/*******************************************************************************
  Function name: GenerateHistory

  Purpose      : Generate a string documenting when and by whom a change was
                 made to the NetCDF file

  Required     : int argc     - number of strings
                 char **argv  - pointer to array of strings
		 char *History - history string

  Returns      : 0

  Modifies     : History string

  Comments     : Originally part of another series of programs for NetCDF.  In
                 that case the command-line arguments were recorded in the
		 history.
*******************************************************************************/


/*******************************************************************************
  Function name: ncUpdateGlobalHistory

  Purpose      : Update the global history attribute or create one if it does
                 not exist.

  Required     : int argc     - number of strings
                 char **argv  - pointer to array of strings
		 int ncid     - NetCDF file id

  Returns      : status (NC_NOERR if successful)

  Modifies     : History attribute

  Comments     : File has to be in define mode before calling ths function.
                 Originally part of another series of programs for NetCDF.  In
                 that case the command-line arguments were recorded in the
		 history.
*******************************************************************************/


/* End of Main. */


/* End of function. */


/*****************************************************************************
  Function name: CreateFileBin()

  Purpose      : Open and close a new file.  If the file already exists it
                 will be overwritten.

  Required     :
    FileName  - Name of the new file
    FileLabel - String describing file contents (currently not used for
                binary IO

  Returns      : void

  Modifies     :

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: MakeFileNameBin()

  Purpose      : Create a new file name ending in extension ".bin" to
                 indicate that the file is binary

  Required     :
    Path     - directory for files
    Str1     - first part of filename
    Str2     - second part of filename
    FileName - filename

  Returns      : void

  Modifies     : FileName

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: Write2DMatrixBin()

  Purpose      : Function to write a 2D array to a file.  Data is appended to
                 the end of the file.

  Required     :
    NY         - Number of rows
    NX         - Number of columns
    NumberType - code for number type (taken from HDF, see comments at the
                 beginning of InitFileIO.c for more detail)
    DataLabel  - string describing the data (currently not used for binary
                 data)
    Units      - string describing the units of the data (currently not
                 used for binary data)
    Matrix     - address of array containing matrix elements
    FileName   - name of output file

  Returns      : Number of elements written

  Modifies     :

  Comments     :
*****************************************************************************/


/* -------------------------------------------------------------
channel_grid_inc_melt
Given a flow (or actually mass), this function increases the inflow contributed
from melt to any channel(s) in the cell in proportion to their length within the
cell.
------------------------------------------------------------- */


/* -----------------------------------------------------------------------------------
   Function name : channel_grid_inc_other ()
   Author: Nathalie Voisin Aug 2010
   Function usage:
   This function generates outputs required by John's RBM model

   Given a mass/flux, this function increases the mass/flux in any
   channel(s) is in proportion to their length within the cell
   BECAUSE THOSE ARE NRG fluxes, similar to each segment
   --------------------------------------------------------------------------------- */


/*************************************************************************************
void channel_grid_avg( ): average the heat budget variables by the total cell numbers
*************************************************************************************/


/*********************************************************************************
Init_segment_ncell : computes the number of grid cell contributing to one segment
**********************************************************************************/


/********************************************************************************
Function Name: CanopyGapRadiation()

Purpose      : Calculate net radiation incident on canopy gap

Required     :
h        - canopy height
dm       - canopy opening diameter (assuming a cylindrical gap)
Rsb      - downward beam radiation (W/m^2)
Rsd      - downward diffuse radiation
Extn     - light extinction coeff.
SunAngle - sine of solar altitude

Returns      :
Comments     :
********************************************************************************/


/********************************************************************************
Function Name: CanopyGapShortRadiation()
********************************************************************************/


/********************************************************************************
Function Name: CanopyGapLongRadiation()
Purpose      : Calculate net long radiation incident on canopy gap
********************************************************************************/


/********************************************************************************
Function Name: GapSurroundingLongRadiation()
********************************************************************************/


/********************************************************************************
Function Name: GapSurroundingShortRadiation()
********************************************************************************/


/********************************************************************************
Function Name: AreaIntegral()

Purpose      : Calculate the integral of an areal function

Required     :
               xmax - the upper bound of x, which is the distance between any point
                      along the optical axis to gap center
               xmin - the lower bound of x

Returns      :
Comments     :
********************************************************************************/


/********************************************************************************
Function Name: CalcGapView()
********************************************************************************/


/*****************************************************************************
  AggregateRadiation()

  In the current implementation the local radiation elements are not stored
  for the entire area.  Therefore these components are aggregated here.  They
  are averaged over the basin in Aggregate()
*****************************************************************************/


/*****************************************************************************
   Function name: MassRelease()

   Purpose      : Calculates mass release of snow from canopy

   Required     :
     float *InterceptedSnow
     float *TempInterceptionStorage
     float *ReleasedMass
     float *Drip

   Returns      : none

   Modifies     : see under required (i.e. all variables are modified)

   Comments     :
 *****************************************************************************/


/*****************************************************************************
  Function name: InitFloatTable()

  Purpose      : Initialize a table structure

  Required     :
    unsigned long Size        - Number of entries in the lookup table
    float Offset              - Value of key for first entry in the table
    float Delta               - Key interval
    float (*Function)(float)  - Function used to fill the table entries
    FLOATTABLE *Table         - pointer to structure that holds the table

  Returns      : void

  Modifies     : FLOATTABLE *table

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: FloatLookup()

  Purpose      : Lookup a table entry corresponding to key x

  Required     :
    float x           - key to be looked up
    FLOATTABLE *Table - Table structure that contains the entries

  Returns      : float

  Modifies     : None

  Comments     :
*****************************************************************************/


/*****************************************************************************
InitAggregated()

Allocates memory for the structure that will hold basin total and/or basin
average values
*****************************************************************************/


/*****************************************************************************
   Function name: CalcAerodynamic()

   Purpose      : Calculate the aerodynamic resistance for each vegetation
                  layer, and the wind 2m above the layer boundary.  In case of
                  an overstory, also calculate the wind in the overstory.
                  The values are normalized based on a reference height wind
                  speed, Uref, of 1 m/s.  To get wind speeds and aerodynamic
                  resistances for other values of Uref, you need to multiply
                  the here calculated wind speeds by Uref and divide the
                  here calculated aerodynamic resistances by Uref

   Required     :
     int NVegLayers - Number of vegetation layers
     char OverStory - flag for presence of overstory.  Only used if NVegLayers
                      is equal to 1
     float Zref     - Reference height for windspeed
     float n        - Attenuation coefficient for wind in the overstory
     float *Height  - Height of the vegetation layers (top layer first)
     float Trunk    - Multiplier for Height[0] that indictaes the top of the
                      trunk space
     float *U       - Vector of length 2, with wind for vegetation layers
                      If OverStory == TRUE the first value is the wind in
                      the overstory canopy, and the second value the wind
                      2m above the lower boundary.  Otherwise the first
                      value is the wind 2m above the lower boundary and
                      the second value is not used.
     float *U2mSnow - Wind velocity 2m above the snow surface
     float *Ra      - Vector of length 2, with aerodynamic resistance values.
                      If OverStory == TRUE the first value is the aerodynamic
                      resistance for the the overstory canopy, and the second
                      value the aerodynamic resistance for the lower boundary.
                      Otherwise the first value is the aerodynamic resistance
                      for the lower boundary and the second value is not used.
     float *RaSnow  - Aerodynamic resistance for the snow surface.

   Returns      : void

   Modifies     :
     float *U
     float *U2mSnow
     float *Ra
     float *RaSnow

   Comments     :
 *****************************************************************************/


/*****************************************************************************
  Function name: CalcTotalWater()

  Purpose      : Calculate the total amount of water in the soil column,
                 corrected for the effects of road cut-banks and channels in
                 grid cells

  Required     :
    int NSoilLayers  - Number of soil layers
    float TotalDepth - Total thickness of the soil column (m)
    float *RootDepth - Array with thicknesses of root layers (m)
    float *Moist     - Array with soil moisture in each layer
    float *Adjust    - Array with coefficients to correct for loss of soil
                       storage due to channel/road-cut for each soil layer.
                       Multiplied with RootDepth to give the zone thickness
                       for use in calculating soil moisture

  Returns      :
    float TotalWater - Total amount of water in the soil profile (m)

  Modifies     : void

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: SolarAngle()

  Purpose      : this subroutine uses solar radiation measured on a horizontal
                 surface to calculate direct, diffuse, and incoming reflected
                 solar radiation for a sloping surface.

  Required     :
    float Latitude	        - site laditude (rad)
    float Albedo                - surface Albedo
    float Declination	        - solar Declination (rad)
    float CellAspect	        - cell aspect (rads eastward from north)
    float CellSlope	        - ground surface slope (rads)
    float SineSolarAltitude	- sine of sun's SolarAltitudede
    float SunMax                - calculated solar radiation at the top of
                                  the atmosphere (W/m^2)
    float SolarTimeStep         - fraction of the timestep the sun is above
                                  the horizon
    int DayLight	        - FALSE: measured solar radiation and the sun
                                  is below the horizon.
                                  TRUE: sun is above the horizon
     float SolarAzimuth    -  solar azimuth (rads eastward from north)
    float Dt			- length of current timestep (hr)

  Returns      : void

  Modifies     :
    float *Direct  - direct beam solar radiation (W/m^2)
    float *Diffuse - diffuse solar radiation (W/m^2)

  Comments     : EXECUTE EACH TIMESTEP FOR EACH GRID CELL
                 Source:  Gates, D.M., "Biophysical ecology",
                 Springer-Verlag,  New York, etc.,  1980.
                 Especially Chapter 6, p. 136 ->
*****************************************************************************/


/*****************************************************************************
  Function name: SolarConst()

  Purpose      : this subroutine reads in site data, calculates constants,
                 and converts data from degrees to radians.

  Required     :
    float lat_deg           - latitude of site in degrees
    float lat_min           - latitude of site in minutes
    float lng_deg           - longitude of site in degrees
    float lng_min           - longitude of site in minutes
    float *StandardMeridian - standard meridian for local time zone in
                              degrees

  Returns      : void

  Modifies     :
    float *Latitude         - latitude of site in radians
    float *Longitude        - longitude of site in radians
    float *StandardMeridian - standard meridian for local time zone (rads)

  Comments     : EXECUTE ONCE BEFORE TIME LOOP
*****************************************************************************/


/* -------------------------------------------------------------
   channel_save_outflow_cplmt
   Saves the channel outflow using a text string as the time field
   for John's RBM model
   ------------------------------------------------------------- */


/******************************************************************************/
/*			     GregorianToJulianDay()                           */
/******************************************************************************/
/*
** Takes a date, and returns a Julian day. A Julian day is the number of
** days since some base date  (in the very distant past).
** Handy for getting date of x number of days after a given Julian date
** (use jdate to get that from the Gregorian date).
** Author: Robert G. Tantzen, translator: Nat Howard
** Translated from the algol original in Collected Algorithms of CACM
** (This and jdate are algorithm 199).
** Copied from the xmgr auxiliary functions Mon Feb  1 14:16:40 1999
*/


/******************************************************************************/
/*			     JulianDayToGregorian()                           */
/******************************************************************************/
/* Julian date converter. Takes a julian date (the number of days since
** some distant epoch or other), and returns an int pointer to static space.
** ip[0] = month;
** ip[1] = day of month;
** ip[2] = year (actual year, like 1977, not 77 unless it was  77 a.d.);
** ip[3] = day of week (0->Sunday to 6->Saturday)
** These are Gregorian.
** Copied from Algorithm 199 in Collected algorithms of the CACM
** Author: Robert G. Tantzen, Translator: Nat Howard
** Copied from the xmgr auxiliary functions Mon Feb  1 14:16:40 1999
*/


/*****************************************************************************
  Function name: AdjustStorage()

  Purpose      : This subroutine calculates corrections to adjust for the
                 effects of road cut-banks and channels in grid cells by
                 calling the function CutBankGeometry().

  Required     :
    int NSoilLayers  - Number of soil layers
    float TotalDepth - Total thickness of the soil column (m)
    float *RootDepth - Array with thicknesses of root layers (m)
    float Area       - Area of channel or road surface (m)
    float DX         - Grid cell width (m)
    float DY         - Grid cell width (m)
    float BankHeight - Distance from ground surface to channel bed or bottom
                       of road-cut (m)

  Returns      : void

  Modifies     :
    float *PercArea  - Array with area of the bottom of zone i, for perc
                       (m/m). This is number between 0 and 1
    float *Adjust    - Array with coefficients to correct for loss of soil
                       storage due to channel/road-cut for each soil layer.
                       Multiplied with RootDepth to give the zone thickness
                       for use in calculating soil moisture
    int *CutBankZone - Number of the soil layer containing the bottom of the
                       cut-bank. Used in UnsaturatedFlow to check for surface
                       runoff.  If BankHeight = 0.; CutBankZone = NO_CUT.

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: CutBankGeometry()

  Purpose      : This subroutine calculates corrections to adjust for the
                 effects of road cut-banks and channels in grid cells.  It
                 also add precip and updates the upper zone soil
                 moisture.  If the water table is below the road /
                 channel bed precip is added to the coresponding zone.

  Required     :
    int i            - Number of the soil layer being processed.
    float RootDepth  - Depth of the soil layer being processed (m)
    float TopZone    - Distance from the ground surface to top of zone i (m)
    float BankHeight - Distance from ground surface to channel bed or bottom
                       of road-cut (m)
    float Area       - Area of channel or road surface (m)
    float DX         - Grid cell width (m)
    float DY         - Grid cell width (m)

  Returns      : void

  Modifies     :
    float *PercArea  - Area of the bottom of zone i, for perc (m/m)
    float *Adjust    - Corrects for loss of soil storage due to channel/
                       road-cut.  Multiplied with RootDepth to give the zone
                       thickness for use in calculating soil moisture
    int *CutBankZone - Number of the soil layer containing the bottom of the
                       cut-bank.  Used in UnsaturatedFlow to check for
                       surface runoff.  If BankHeight = 0.; CutBankZone =
                       NO_CUT

  Comments     :
    Schematic:

    <-----------------------------------DX---------------------------------->
    |====================|     -                     |======================|
    |      ^             |     |                     |   |                  |
    |      TopZone[0]    |<----|------Area---------->|   |- RootDepth[0]    |
    |                    |     |                     |   |                  |
    |<---PercArea*DX---->|     |                     |<--|--PercArea*DX---->|
    |                    |     |-BankHeight          |   V                  |
    |====================|     |                     |======================|
    |       ^            |     |                     |   |                  |
    |       TopZone[1]   |     |                     |   |-RootDepth[1]     |
    |                    |     V                     |   |                  |
    |                    |---------------------------|   |                  |
    |                                                    |                  |
    |                             CutBankZone            V                  |
    |=======================================================================|
    |                                                                       |
    |                                                                       |
    |=======================================================================|

    Note: if the cut bank is cause by a road instead of a channel, then the
          schematic would look as follows:

          |=================|
          |                 |
          |=================|
          |                 |_______________
          |                                 |
          |=================================|
          |                                 |
          |=================================|
*****************************************************************************/


/*****************************************************************************
RouteSurface()
If the watertable calculated in WaterTableDepth() was negative, then water is
ponding on the surface.  At the moment no ponding of water is allowed in
DHSVM, and the "excess" water is routed to the outlet one pixel per time step
However, if the pixel contains an impervious fraction, then the surface water
is immediately routed to the nearest downslope pixel that contains a channel.
The net effect is that all pixels that have an impervious area are directly
connected (over the coarse of a single time step) to the channel network, this
assumption is likely to be true for small urban basins, and perhaps even for
large rural basins with some urban development
If Overland Routing = KINEMATIC, then "excess" water is routed to the outlet
using a infinite difference approximation to the kinematic wave solution of
the Saint-Venant equations.
*****************************************************************************/


/*****************************************************************************
  Function name: NoSensibleHeatFlux()

  Purpose      : Calculate latent heat flux in W/m2

  Required     :
    int Dt             - Model timestep (seconds)
    PIXMET LocalMet    - Met data for the current pixel
    float ETot         - Total vapor flux (mm/timestep)
    SOILPIX *LocalSoil - Structure with soil moisture data and energy data
                         for the current pixel

  Returns      :
    void

  Modifies     :
    members of LocalSoil

  Comments     : This function sets all the energy fluxes at the pixel level
                 to 0.0, but calculates the evapotranspiration in W/m2
*****************************************************************************/


/*****************************************************************************
   Function name: InitNetwork()

   Purpose      : Initialize road/channel work.  Memory is allocated, and the
                  necessary adjustments for the soil profile are calculated

   Comments     :
 *****************************************************************************/


/*****************************************************************************
  MassBalance()

  Calculate the average values for the different fluxes and state variables
  over the basin.
  In the current implementation the local radiation
  elements are not stored for the entire area.  Therefore these components
  are aggregated in AggregateRadiation() inside MassEnergyBalance().

  The aggregated values are set to zero in the function RestAggregate,
  which is executed at the beginning of each time step.
*****************************************************************************/


/*****************************************************************************
  Function name: CalcVaporPressure()

  Purpose      : Calculates the saturated vapor pressure in Pa for a certain
                 temperature in degrees C

  Required     :
    float T    - Temperature (C)

  Returns      :
    float      - Saturated vapor pressure (Pa)

  Modifies     : none

  Comments     :
    References: Shuttleworth, W.J., Evaporation,  In: Maidment, D. R. (ed.),
                  Handbook of hydrology,  1993, McGraw-Hill, New York, etc..
                Bras, R. A., Hydrology, an introduction to hydrologic
                  science, Addisson Wesley, Inc., Reading, etc., 1990.

*****************************************************************************/


/*****************************************************************************
   StoreModelState()

   Store the current state of the model.

   The state variables for DHSVM include the following variables:

     - Canopy interception for each vegetation layer

     - Snow pack conditions:
       - presence/absence
       - number of days since last snowfall (used in albedo calculation)
       - snow water equivalent
       - for each layer of the snow pack:
         - liquid water content
         - temperature
       - cold content

     - Soil conditions:
       - for each soil layer:
         - soil moisture (also for the layer below the deepest root zone)
         - temperature
       - surface temperature
       - ground heat storage
 *****************************************************************************/


/** Destroy the buffer.
 * @param b a buffer created with table_yy_create_buffer()
 *
 */


/* Initializes or reinitializes a buffer.
 * This function is sometimes called more than once on the same buffer,
 * such as during a table_yyrestart() or at EOF.
 */


/* table_yylex_destroy is for both reentrant and non-reentrant scanners. */


/* -------------------------------------------------------------
   table_open

   opens the specified file and sets up the scanner.  Zero is returned
   if all goes well
   ------------------------------------------------------------- */


/* -------------------------------------------------------------
   table_get_fields

   This is used to read a record from the file and decide if errors
   have occurred. Zero is returned if a record is read OK, -1 if the
   end of file was reached, a positive integer if errors occured.
   This assumes table_open has been called.
   ------------------------------------------------------------- */


/*******************************************************************************
  Function name: InitFileIO()

  Purpose      : Initialize function pointers for file IO

  Required     :
    int FileFormat - identifier for the file format to be used

  Returns      : void

  Modifies     : function pointers for file IO

  Comments     :

  This function sets the file pointers for file I/O functions to the
  functions that implement the desired file format.  By using file pointers,
  the main routines do not need to be changed if a new file format is to be
  supported in the future (at least that is what I am trying to accomplish).
  The only thing that will need to be done is write the necessary I/O
  functions for the new file format, and add the additional options to this
  initialization routine.

  For example: Currently three different file formats are supported, i.e.
  (plain vanilla) binary, swapped binary, and NetCDF v 3.4. (HDF v. 3.3 support
  has been discontinued as of Mon Jan 25 1999).  The user can specify which file
  format is to be used, and then the function pointer for the function
  Read2DMatrix will be set to Read2DMatrixBin, Read2DMatrixByteSwapBin, or
  Read2DMatrixNetCDF.  In the remaining part of the program this change is
  transparent, and the function call used to read a matrix is Read2DMatrix for
  either case.

  Information is stored in all files in the following way:
  fastest varying dimension: X (West to East)
  next fastest dimension   : Y (North to South)
          .                : Variable (if more than one)
  slowest varying dimension: Time (if more than one timestep)
  All the information is written out or read in for one timestep at a time.

  The following terminology is used (this is not based on anything
  "official", and may (will) not correspond to either dictionary or
  scientific definitions, but there is only so much one can do with variable
  and function names).  Some of the distinctions being made may not always
  seem to make sense for certain file formats, and partly result from the
  fact that the first version of the model used the HDF file format:
   - 2DMatrix :
       a map layer with X and Y dimension.
   - 2DImage :
       a map layer with X and Y dimension in which the data are stored as
       unsigned char, i.e. values in the interval [a, b] are mapped to numbers
       in the range [0, 255].

   In order to use the NetCDF functions the NetCDF library needs to be
   installed on your system.  If this is the case, HAVE_NETCDF needs to be
   defined at compile time.  If it is not defined the NetCDF functions cannot be
   used, and DHSVM will not try to access the NetCDF libraries.
*******************************************************************************/


/******************************************************************************/
/*                              Read2DMatrix                                  */
/******************************************************************************/
/**
 *
 *
 * @param FileName name of file to read
 * @param Matrix  @e local 2D array (NX, NY) to be filled
 * @param NumberType
 * @param NY
 * @param NX
 * @param NDataSet
 * @param VarName
 * @param index
 *
 * @return
 */


/*****************************************************************************
  Function name: SeparateRadiation()

  Purpose      : Separate observed downward solar radiation into diffuse and
                 direct beam radiation based on the clearness index (kt)

  Required     :
    float TotalSolar - Total amount of solar (shortwave) radiation (W/m2)
    float ClearIndex - Clearness index
    float *Beam      - Direct beam radiation (W/m2)
    float *Diffuse   - Diffuse radiation (W/m2)

  Returns      : void

  Modifies     :
    float *Beam      - Direct beam radiation (W/m2)
    float *Diffuse   - Diffuse radiation (W/m2)

  Comments     : Based on: Erbs, D.G., S.A. Klein, and J.A. Duffie,
                 "Estimation of the diffuse fraction for hourly, daily and
                 monthly-average global radiation", Solar Energy, V.28, n.4,
                 pp.293-302, 1982
*****************************************************************************/


/*****************************************************************************
  Function name: CalcKhDry()

  Purpose      : This function calculates the thermal conductivity of a soil
                 under dry conditions, KhDry, based on the soil density. This
                 is an empirical relationship which supposedly is accurate to
                 within 20% [Farouki, 1986; section 3.3.2].

  Required     :
    float Density - Soil bulk density in kg/m3

  Returns      : KhDry - Soil thermal conductivity

  Modifies     : NA

  Comments     : Source: Farouki, O. T., 1986, Thermal properties of soils,
                 Trans Tech Publications

*****************************************************************************/


/*****************************************************************************
  ReadChannelState()

  Read the state of the channel from a previous run.  Currently just read an
  ASCII file, with the unique channel IDs in the first column and the amount
  of storage in the second column (m3)
*****************************************************************************/


/*****************************************************************************
  StoreChannelState()

  Store the current state of the channel, i.e. the storage in each channel
  segment.

*****************************************************************************/


/*****************************************************************************
  CompareRecord()

  Compare two RECORDSTRUCT elements for qsort
*****************************************************************************/


/*****************************************************************************
  CompareRecordID()

  Compare RECORDSTRUCT element with an ID to see if the RECORDSTRUCT has the
  right ID for bsearch
*****************************************************************************/


/*****************************************************************************
  Aggregate()

  Calculate the average values for the different fluxes and state variables
  over the basin.  Only the runoff is calculated as a total volume instead
  of an average.  In the current implementation the local radiation
  elements are not stored for the entire area.  Therefore these components
  are aggregated in AggregateRadiation() inside MassEnergyBalance().

  The aggregated values are set to zero in the function RestAggregate,
  which is executed at the beginning of each time step.
*****************************************************************************/


/*******************************************************************************
   Function name: InitDump()

   Purpose      : Read the model output information from the options file, and
                  organize what to output when.  This information is in the
          [OUTPUT] section

   Required     :
     LISTPTR Input         - Linked list with input strings
     OPTIONSTRUCT *Options - Mode options
     MAPSIZE *Map          - Information about basin area
     int MaxSoilLayers     - Maximum number of soil layers
     int MaxVegLayers      - Maximum number of vegetation layers
     int Dt                - Time step in seconds
     TOPOPIX **TopoMap     - Information about terrain characteristics
     DUMPSTRUCT *Dump      - Information on what to output when

   Returns      : void

   Modifies     : Members of Dump

   Comments     :
 *****************************************************************************/


/*******************************************************************************
  Function name: InitGraphicsDump()

  Purpose      : Initialize the model state dumps.  This information is in the
         [OUTPUT] section of the input file

  Required     :
    LISTPTR Input         - Linked list with input strings
    int NStates           - Number of graphics to display
    int *which_graphics        - Array with graphic id's

  Returns      : void

  Modifies     : which_graphics, NStates

  Comments     :
*****************************************************************************/


/*******************************************************************************
  Function name: InitStateDump()

  Purpose      : Initialize the model state dumps.  This information is in the
         [OUTPUT] section of the input file

  Required     :
    LISTPTR Input         - Linked list with input strings
    int NStates           - Number of model states to dump
    DATE **DState         - Array with dump dates

  Returns      : void

  Modifies     : DState and its members

  Comments     :
*****************************************************************************/


/*******************************************************************************
  Function name: InitImageDump()

  Purpose      : Initialize the image dumps.  This information is in the
         [OUTPUT] section of the input file

  Required     :
    LISTPTR Input         - Linked list with input strings
    int Dt                - Model timestep in seconds
    MAPSIZE *MapDump      - Information about areal extent
    int MaxSoilLayers     - Maximum number of soil layers
    int MaxVegLayers      - Maximum number of vegetation layers
    char *Path            - Directory to write output to
    int NMaps             - Number of maps to dump
    int NImages           - Number of images to dump
    MAPDUMP **DMap        - Array of maps and images to dump

  Returns      : void

  Modifies     : Members of DMap

  Comments     : InitImageDump must be preceded by a call to InitMapDump, since
                 the necessary memory is allocated there
*******************************************************************************/


/*******************************************************************************
  Function name: InitMapDump()

  Purpose      : Initialize the map dumps.  This information is in the
         [OUTPUT] section of the input file

  Required     :
    LISTPTR Input         - Linked list with input strings
    MAPSIZE *MapDump      - Information about areal extent
    int MaxSoilLayers     - Maximum number of soil layers
    int MaxVegLayers      - Maximum number of vegetation layers
    char *Path            - Directory to write output to
    int NTotalMapImages   - Total number of maps and images to dump
    int NMaps             - Number of maps to dump
    MAPDUMP **DMap        - Array of maps and images to dump

  Returns      : void

  Modifies     : DMap and its members

  Comments     :
*******************************************************************************/


/*******************************************************************************
  Function name: InitPixDump()

  Purpose      : Initialize the pixel dumps.  This information is in the
         [OUTPUT] section of the input file

  Required     :
    LISTPTR Input         - Linked list with input strings
    MAPSIZE *Map          - Information about basin extent
    uchar **BasinMask     - Basin mask
    char *Path            - Directory to write output to
    int NPix              - Number of pixels to dump
    PIXDUMP **Pix         - Array of pixels to dump

  Returns      : number of accepted dump pixels (i.e. in the mask, etc)

  Modifies     : NPix and its members

  Comments     :
*******************************************************************************/


/*****************************************************************************
  Function name: CalcSatDensity()

  Purpose      : This function calculates the daturated soil density.

  Required     :
    float Density - Soil bulk density in kg/m3

  Returns      : SatDensity - Saturated Soil Density

  Modifies     : NA

  Comments     :

*****************************************************************************/


/*****************************************************************************
Function name: SnowInterception()

Purpose      : Calculate snow interception and release by the canopy

Required     :
int y                  - Row counter
int x                  - Column counter
int Dt                 - Model timestep (seconds)
float F                - Fractional coverage
float LAI              - Leaf Area Index
float MaxInt           - Maximum rainfall interception storage (m)
float BaseRa           - Aerodynamic resistance (uncorrected for
stability) (s/m)
float AirDens          - Density of air (kg/m3)
float EactAir          - Actual vapor pressure of air (Pa)
float Lv               - Latent heat of vaporization (J/kg3)
PIXRAD *LocalRad       - Components of radiation balance for current pixel
(W/m2)
float Press            - Air pressure (Pa)
float Tair             - Air temperature (C)
float Vpd	           - Vapor pressure deficit (Pa)
float Wind             - Wind speed (m/s)
float *RainFall        - Amount of rain (m)
float *Snowfall        - Amount of snow (m)
float *IntRain         - Intercepted rain (m)
float *IntSnow         - Snow water equivalent of intercepted snow (m)
float *TempIntStorage  - Temporary storage for snowmelt and rainfall
involved in mass release calculations (m)
float *VaporMassFlux   - Vapor mass flux to/from intercepted snow
(m/timestep)
float *Tcanopy         - Canopy temperature (C)
float *MeltEnergy      - Energy used in heating and melting of the snow
(W/m2)
float *Height          - Height of vegetation (m)

Returns      : none

Modifies     :
float *RainFall        - Amount of rain (m)
float *Snowfall        - Amount of snow (m)
float *IntRain         - Intercepted rain (m)
float *IntSnow         - Snow water equivalent of intercepted snow (m)
float *TempIntStorage  - Temporary storage for snowmelt and rainfall
involved in mass release calculations (m)
float *VaporMassFlux   - Vapor mass flux to/from intercepted snow
(m/timestep)
float *Tcanopy         - Canopy temperature (C)

Comments     : Only the top canopy layer is taken into account for snow
interception.  Snow interception by lower canopy is
disregarded.  Rain water CAN be intercepted by lower canopy
layers (similar to InterceptionStorage()).
Of course:  NO vegetation -> NO interception
*****************************************************************************/


/*****************************************************************************
  CalcSnowAlbedo()

  Source:
  Laramie, R. L., and J. C. Schaake, Jr., Simulation of the continuous
  snowmelt process, Ralph M. Parsons Laboratory, Mass. Inst. of Technol.,
  1972

  Snow albedo is calculated as a function of the number of days since the
  last observed snow fall. There are separete albedo curves for the freeze
  and thaw conditions.
*****************************************************************************/


/* -------------------------------------------------------------
   slope_aspect
   Calculation of slope and aspect given elevations of cell and neighbors
   ------------------------------------------------------------- */


/* -------------------------------------------------------------
   flow_fractions
   Computes subsurface flow fractions given the slope and aspect

   Comment: this function is considerably modified to avoid any
   out flow to the cells outside of the basin mask (Ning, 2013)
------------------------------------------------------------- */


/* -------------------------------------------------------------
   HeadSlopeAspect
   This computes slope and aspect using the water table elevation.

   Comment: rewritten to fill the sinks (Ning, 2013)
   ------------------------------------------------------------- */


/* -------------------------------------------------------------
SnowSlopeAspect
This computes slope and aspect using the SnowSurface Elevation.
------------------------------------------------------------- */


/*****************************************************************************
   Function name: CalcWeights()

   Purpose      : Calculate interpolation weights to interpolate the
                  meteorological data from the various stations for every
                  individual pixel

   Required     :
     METLOCATION *Station - Location of meteorological stations
     int NStats           - Number of meteorological stations
     int NX               - Number of pixels in East - West direction
     int NY               - Number of pixels in North - South direction
     uchar ** BasinMask   - BasinMask
     uchar ***WeightArray - 3D array with interpolation weights

   Returns      :  void

   Modifies     :
     The values stored at the addresses pointed to by WeightArray (i.e. it
     calculates the weights and stores them)

   Comments     :
 *****************************************************************************/


/* -------------------------------------------------------------
channel_read_classes
This function opens and reads the specified file and returns a
linked list of ChannelClass structs.  If anything goes wrong, NULL
is returned and any ChannelClass structs are destroyed.
------------------------------------------------------------- */


/* -------------------------------------------------------------
channel_find_segment
A simple linear search of the channel network to find a segment
with the given id
------------------------------------------------------------- */


/* -------------------------------------------------------------
channel_save_outflow
This routine saves the channel output
------------------------------------------------------------- */


/* -------------------------------------------------------------
channel_save_outflow_wtext
Saves the channel outflow using a text string as the time field
------------------------------------------------------------- */


/*****************************************************************************
  Function name: CalcTransmissivity()

  Purpose      : Calculates the transmissivity through the saturated part of
                 the soil profile

  Required     :
    float SoilDepth  - Total soil depth in m
    float WaterTable - Depth of the water table below the soil surface in m
    float LateralKs  - Lateral hydraulic conductivity in m/s
    float KsExponent - Exponent that describes exponential decay of LateralKs
                       with depth below the soil surface

  Returns      : Transmissivity in m2/s

  Modifies     : NA

  Comments     :
    Source:
    Wigmosta, M. S., L. W. Vail, and D. P. Lettenmaier, A distributed
      hydrology-vegetation model for complex terrain, Water Resour. Res.,
      30(6), 1665-1679, 1994.

    Based on:
    Beven, K. J., On subsurface stormflow:  An analysis of response times,
      Hydrolog. Sci. J., 4, 505-521, 1982.

    The hydraulic conductivity is assumed exponentially with depth, based on
    material in Beven [1982].
*****************************************************************************/


/*****************************************************************************
  RouteSubSurface()

  Sources:
  Wigmosta, M. S., L. W. Vail, and D. P. Lettenmaier, A distributed
      hydrology-vegetation model for complex terrain, Water Resour. Res.,
      30(6), 1665-1679, 1994.

  Quinn, P., K. Beven, P. Chevallier, and O. Planchon, The prediction of
      hillslope flow paths for distributed hydrological modelling using
      digital terrain models, Hydrological Processes, 5, 59-79, 1991.

  This routine follows Wigmosta et al. [1994] in calculating the subsurface
  flow.  The local gradient is based on the local hydraulic head, consisting
  of the height of the pixel surface minus the depth of the water table
  below the water surface.  This has the disadvantage that the local gradients
  have to be recalculated for each pixel for each timestep.  In Wigmosta et
  al. [1994] the local gradient is taken to be equal to the slope of the land
  surface, which is a reasonable assunption for mountainous areas.  For the
  flat boreal forest landscape it is probably better to use the slope
  of the water surface.

  Set the gradient with pixels that are outside tha basin to zero.  This
  ensures that there is no flux of water across the basin boundary.  In the
  current implementation water can only leave the basin as surface flow.
  This may not be entirely realistic, and should be analyzed further.
  One consequence of this could be that the soil in the basin is more
  saturated than it would be if subsurface flow out of the basin would
  be allowed.

  The surrounding grid cells are numbered in the following way

                |-----| DX

          0-----1-----2  ---
	  |\    |    /|   |
          | \   |   / |   |
          |  \  |  /  |   | DY
          |   \ | /   |   |
          |    \|/    |   |
          7-----*-----3  ---
          |    /|\    |
          |   / | \   |
          |  /  |  \  |
          | /   |   \ |
          |/    |    \|
          6-----5-----4

  For the current implementation it is assumed that the resolution is the
  same in both the X and the Y direction.  If this is not the case an error
  message is generated and the program exits.  The reason is that the
  formulation for the flow width in the diagonal direction changes if the
  grid is not square.  The method for defining the flow widths in the case
  of square grids is taken from Quinn et al [1991]

  Update Jan 2004 COD
  When Gradient = WATERTABLE, the watertable was used to route the
  surface water. This was because of the common use of TopoMap.Dir and
  TopoMap.TotalDir. These are now for surface routing (always) and subsurface
  routing (when Gradient = TOPOGRAPHY). Subsurface routing directions
  and FlowGrad (SubDir, SubTotalDir, SubFlowGrad) for Gradient = WATERTABLE
  are now determined locally here (in RouteSubsurface.c.)

  WORK IN PROGRESS
*****************************************************************************/


/********************************************************************************
Function Name: CanopyGapInterception()

Purpose      : Calculate snow/rain interception
Returns      :
Comments     :
********************************************************************************/


/********************************************************************************
Function Name: CanopyGapSnowMelt()

Purpose      : Calculate snow melt
Returns      :
Comments     :
********************************************************************************/


/*****************************************************************************
Function name: CalcCanopyGapAerodynamic()

Purpose      : Calculate the aerodynamic resistance for each vegetation
layer, and the wind 2m above the layer boundary.
*****************************************************************************/


/*****************************************************************************
Function name: CalcCanopyGapET()

Purpose      : Calculate the ET
*****************************************************************************/


/*****************************************************************************
Function name: CalcGapSurroudingIntercept()

Purpose      : .
*****************************************************************************/


/*****************************************************************************
Function name: CalcGapSurroudingET()

Purpose      :
*****************************************************************************/


/*****************************************************************************
Function name: AggregateCanopyGap()

Purpose      : Aggregate the gap and non-gap mass balance variables based
on area weight.
*****************************************************************************/


/*****************************************************************************
Function name: MakeLocalMetData()

Purpose      : Generates meteorological for each individual cell

Required     :
int y
int x
MAPSIZE Map
int DayStep
unsigned char PrecipType
int NStats
METLOCATION *Stat
uchar *MetWeights
float LocalElev
RADCLASSPIX *RadMap
PRECIPPIX *PrecipMap
MAPSIZE Radar
RADARPIX **RadarMap

Returns      :
PIXMET LocalMet

Modifies     :

Comments     :
Reference: Shuttleworth, W.J., Evaporation,  In: Maidment, D. R. (ed.),
Handbook of hydrology,  1993, McGraw-Hill, New York, etc..
*****************************************************************************/


/*****************************************************************************
   InitNewMonth()
   At the start of a new month, read the new radiation files
   (diffuse and direct beam), and potentially a new LAI value.
 *****************************************************************************/


/*****************************************************************************
  Function name: InitNewDay()

  Purpose      : Initialize the Earth-Sun geometry variables at the beginning
                 of each day

  Required     :
    int DayOfYear           - day of year (January 1 = 1)
    SOLARGEOMETRY *SolarGeo - structure with information about Earth-Sun
                              geometry

  Returns      : void

  Modifies     :
    SOLARGEOMETRY *SolarGeo

  Comments     : To be excuted at the beginning of each new day
*****************************************************************************/


/*****************************************************************************
  Function name: InitNewStep()

  Purpose      : Initialize Earth-Sun geometry and meteorological data at the
                 beginning of each timestep

  Required     :
    MAPSIZE Map              - Structure with information about location
    TIMESTRUCT Time          - Structure with time information
    int PrecipType           - Type of precipitation input, RADAR, STATION or
                               OROGRAPHIC
    int FlowGradient         - Type of FlowGradient calculation
    int NStats               - Number of meteorological stations
    METLOCATION *Stat        - Structure with information about the
                               meteorological stations in or near the study
                               area
    char *RadarFileName      - Name of file with radar images
    MAPSIZE Radar            - Structure with information about the
                               precipitation radar coverage
    RADARPIX **RadarMap      - Structure with precipitation information for
                               each radar pixel
    SOLARGEOMETRY *SolarGeo  - structure with information about Earth-Sun
                               geometry
    SOILPIX **SoilMap        - structure with soil information
    float ***MM5Input        - MM5 input maps
    float ***WindModel       - Wind model maps

  Returns      : void

  Modifies     :

  Comments     : To be executed at the beginning of each time step
*****************************************************************************/


/*****************************************************************************
   InitNewWaterYear()
   At the start of a new water year, re-initiate the SWE stats maps
 *****************************************************************************/


/*****************************************************************************
  Function name: InitConstants()

  Purpose      : Initialize constants and settings for DHSVM run
                 Processes the following sections in InFile:
                 [OPTIONS]
                 [AREA]
                 [TIME]
                 [CONSTANTS}

  Required     :
    LISTPTR Input          - Linked list with input strings
    OPTIONSTRUCT *Options   - Structure with different program options
    MAPSIZE *Map            - Coverage and resolution of model area
    SOLARGEOMETRY *SolarGeo - Solar geometry information
    TIMESTRUCT *Time        - Begin and end times, model timestep

  Returns      : void

  Modifies     : (see list of required above)

  Comments     :
*****************************************************************************/


/*******************************************************************************
   Function name: InitMetSources()

   Purpose      : Initialize and configure the model to process meteorological
                  data from various different sources
                  Processes the following section in the input file:
                  [METEOROLOGY]

   Required     :
     LISTPTR Input           - Linked list with input strings
     OPTIONSTRUCT *Options   - Structure with different program options
     MAPSIZE *Map            - Coverage and resolution of model area
     int NSoilLayers         - Number of soil layers
     TIMESTRUCT *Time        - Begin and end times, model timestep
     INPUTFILES *InFiles     - Various input filenames
     int *NStats             - Number of meteorological stations
     METLOCATION **Stat      - Station information
     MAPSIZE *Radar          - Areal extent of radar files

   Returns      : void

   Modifies     : Members of Time, InFiles, RadClass, and Radar

   Comments     :
 *******************************************************************************/


/*******************************************************************************
  Function name: InitStations()

  Purpose      : Read the station information from the options file.  This
                 information is in the [METEOROLOGY] section

  Required     :
    LISTPTR Input       - Linked list with input strings
    MAPSIZE *Map        - Information about the basin area
    int NDaysSteps      - Number of time steps in a day
    int *NStats         - Number of met stations
    METLOCATION **Stat  - Information about each met station

  Returns      : void

  Modifies     : NStats, Stat and members of Stat

  Comments     :
*****************************************************************************/


/*******************************************************************************
Function name: InitGridMet()

Purpose      : Read the gridded met file.  This information
is in the [METEOROLOGY] section
*****************************************************************************/


/*******************************************************************************
  Function name: InitMM5()

  Purpose      : Read the MM5 information the options file.  This information
                 is in the [METEOROLOGY] section

  Required     :
    LISTPTR Input       - Linked list with input options
    int NSoilLayers     - Number of soil layers
    TIMESTRUCT *Time    - Time information
    INPUTFILES *InFiles - Filenames for various input files

  Returns      : void

  Modifies     : Members of Time and InFiles

  Comments     :
*****************************************************************************/


/*******************************************************************************
  Function name: InitRadar()

  Purpose      : Read the radar information from the options file.  This
                 information is in the [METEOROLOGY] section

  Required     :
    LISTPTR Input       - Linked list with input strings
    MAPSIZE *Map        - Information about basin area
    TIMESTRUCT *Time    - Time information
    INPUTFILES *InFiles - Filenames for various input files
    MAPSIZE *Radar      - Information about radar coverage

  Returns      : void

  Modifies     : Members of Time, InFiles and Radar

  Comments     :
*****************************************************************************/


/*******************************************************************************
  Function name: InitWindModel()

  Purpose      : Read the wind model information from the options file.  This
                 information is in the [METEOROLOGY] section

  Required     :
    LISTPTR Input       - Linked list with input strings
    INPUTFILES *InFiles - Filenames for various input files
    int NStats          - Number of stations
    METLOCATION *Stat   - Information about met stations

  Returns      : void

  Modifies     : Members of InFiles and Stat.  Also a global constant
                 (NWINDMAPS)

  Comments     :
*****************************************************************************/


/*******************************************************************************
  Function name: InitPrecipLapse()

  Purpose      : Read the file name for the precip lapse rate from the options
                 file.  This information is in the [METEOROLOGY] section

  Required     :
    LISTPTR Input       - Linked list with input strings
    INPUTFILES *InFiles - Filenames for various input files

  Returns      : void

  Modifies     : Member of InFiles

  Comments     :
*****************************************************************************/


/*****************************************************************************
  CalcEffectiveKh()

  Source: Farouki, O. T., 1986, Thermal properties of soils,
                          Trans Tech Publications

  This function calculates the effective thermal conductivity of a soil
  based on the thermal conductivity under dry conditions, KhDry, and the
  thermal conductivity under saturated conditions, KhSat.  The latter
  differs for frozen and unfrozen soils, and is function of the effective
  solids thermal conductivity, KhSol, and the saturates soil moisture or
  ice content.

  The method followed here is Johansen's method, section 7.11 [Farouk, 1986]

  First the effective conductivity is calculated for each layer, after which
  the total effective thermal conductivity is calculated for the specified
  depth.
*****************************************************************************/


/*****************************************************************************
Function name: UnsaturatedFlow()

Purpose      : Calculate the unsaturated flow in the soil column, and
adjust the moisture in each soil layer

Required     :
int Dt             - Time step (seconds)
float DX           - Grid cell width (m)
float DY           - Grid cell width (m)
float Infiltration - Amount of infiltration entering the top of the soil
column (m)
float RoadbedInfiltration - Amount of infiltration through the roadbed(m)
float SatFlow      - Amount of saturated flow entering the soil column
from neighbouring pixels (m)
int NSoilLayers    - Number of soil layers
float TotalDepth   - Total depth of the soil profile (m)
float Area         - Area of channel or road surface (m)
float *RootDepth   - Depth of each of the soil layers (m)
float *Ks          - Vertical saturated hydraulic conductivity in each
soil layer (m/s)
float *PoreDist    - Pore size distribution index for each soil layer
float *Porosity    - Porosity of each soil layer
float *FCap        - Field capacity of each soil layer
float *Perc        - Amount of water percolating from each soil layer to
the layer below (m)
float *PercArea    - Area of the bottom of each soil layer as a fraction
of the gridcell area DX*DY
float *Adjust      - Correction for each layer for loss of soil storage
due to channel/road-cut.  Multiplied with RootDepth
to give the layer thickness for use in calculating

soil moisture
int CutBankZone    - Number of the soil layer containing the bottom of

the cut-bank
float BankHeight   - Distance from ground surface to channel bed or
bottom of road-cut (m)

Returns      : void

Modifies     :
float *TableDepth - Depth of the water table below the ground surface (m)
float *RunOff     - Amount of runoff produced at the pixel (m)
float *Moist      - Moisture content in each soil layer

Comments     :
Sources:
Bras, R. A., Hydrology, an introduction to hydrologic science, Addisson
Wesley, Inc., Reading, etc., 1990.
Wigmosta, M. S., L. W. Vail, and D. P. Lettenmaier, A distributed
hydrology-vegetation model for complex terrain, Water Resour. Res.,
30(6), 1665-1679, 1994.

This function is based on Wigmosta et al [1994], and assumes a unit
hydraulic gradient in the unsaturated zone.  This implies a
steady-state situation and uniform moisture distribution.  This is not
unreasonable for situations where the groundwater is fairly deep
[Bras, 1990], but may be unrealistic for the boreal forest system, or
other similar situations where the groundwater table is relatively close
to the surface. The current formulation does not allow for upward
movement of water in the unsaturated zone, by capillary and matrix
forces.  No unsaturated flux is assumed to occur if the water content
drops below the field capacity.

The unsaturated hydraulic conductivity is calculated using the
Brooks-Corey equation see for example Wigmosta et al. [1994], eq.41

The calculated amount of drainage is averaged with the amount calculated
for the previous timestep, see eq. 42 [Wigmosta et al., 1994].

The residual moisture content is assumed to be zero (easy to adapt if
needed).

If the amount of soil moisture in a layer after drainage still
exceeds the porosity for that layer, this additional amount of water is
added to the drainage to the next layer.

CHANGES:

Changes have been made to account for the potental loss of soil storage
in a grid cell due to a road-cut or channel.  Correction coefficents are
calculated in AdjustStorage() and CutBankGeometry()
*****************************************************************************/


/*****************************************************************************
   Function name: RadiationBalance()

   Purpose      : Calculate the radiation balance for the individual canopy layers

   Required     :
     int HeatFluxOption - TRUE if surface temperature is being calculated
     float Rs           - Incoming shortwave radiation adjusted by topo shading
                          if shading option is on (W/m2)
     float Rsb          - Incoming direct shortwave radiation separated from Rs
     float Rsd          - Incoming diffuse shortwave radiation separated from Rs
     float VIC_Rs       - Input 'observed' shortwave radiation in the forcing file
     float Ld           - Incoming longwave radiation (W/m2)
     float Tair         - Ambient air temperature (C)
     float Tcanopy      - Canopy temperature from the previous timestep (C)
     float Tsoil        - soil surface temperature from the previous timestep (C)
     int NAct           - Number of vegetation layers above the snow
     VEGTABLE VType     - Information about number of veg layers
     SNOWPIX LocalSnow  - Information about snow conditions at current pixel
     PIXRAD *LocalRad   - Components of radiation balance for current pixel

   Returns      : void

   Modifies     :
     PIXRAD *LocalRad  - Components of radiation balance for current pixel

   Comments     :
     This routine is implemented according to Wigmosta et al. (1994), with a
     small change for the soil surface temperature if a sensible heat flux is
     calculated, and the canopy surface temperature.
     The following assumptions are made:
       - No snow:
         soil temperature is TSurf from last timestep if HeatFluxOption ==
         TRUE, otherwise the soil temperature is the same as the air
         temperature
       - Snow:
         soil temperature is the snow surface temperature
       - Canopy temperature is equal to the air temperature is there is no snow
         interception
       - There are at most two vegetation layers

 *****************************************************************************/


/************************************************************************************************
  Function name: LongwaveBalance()

  Purpose      : Calculate the longwave radiation balance for the individual
                 canopy layers

  Required     :
    unsigned char OverStory
                     - Flag to indicate presence/absence of overstory
    float F          - Fraction of pixel covered by top vegetation layer
    float Ld         - Downward (incoming) longwave radiation (W/m2)
    float Tcanopy    - Canopy temperature (C)
    float Tsurf      - Surface temperature (C)
    PIXRAD &LocalRad - Components of radiation balance for current pixel

  Returns      :
    void

  Modifies     :
    Elements of LocalRad

  Comments     : This function is used to update the longwave radiation
                 balance when new surface temperatures are calculated
************************************************************************************************/


/*****************************************************************************
  Function name: ShortwaveBalance()

  Purpose      : Calculate the shortwave radiation balance for the individual
                 pixels

  Required     :
    unsigned char OverStory
                     - Flag to indicate presence of overstory
    float F          - Fraction of pixel covered by top vegetation layer
    float Rs         - Incoming shortwave radiation (W/m2)
    float Tau        - Canopy transmittance coefficient for overstory
    float *Albedo    - Albedo of each layer
    PIXRAD *LocalRad - Components of radiation balance for current pixel

  Returns      :
    void

  Modifies     :
    Elements of LocalRad

  Comments     :
    This function needs to be called only once for each pixel for each
    timestep, since the shortwave radiation balance is independent of
    the surface temperatures
*****************************************************************************/


/****************************************************************************
   Function name: CalcAvailableWater()

   Purpose      : This routine calculates the amount of soil moisture
                  available for saturated flow below the groundwater table.
                  No flow is allowed to occur if the moisture content falls
                  below the field capacity.

   Required     :
     int NRootLayers  - Number of soil layers
     float TotalDepth - Total depth of the soil profile (m)
     float *RootDepth - Depth of each of the soil layers (m)
     float *Porosity  - Porosity of each soil layer
     float *FCap      - Field capacity of each soil layer
     float TableDepth - Depth of the water table below the surface (m)
     float *Adjust    - Correction for each layer for loss of soil storage
                        due to channel/road-cut.  Multiplied with RootDepth
                        to give the layer thickness for use in calculating
                        soil moisture

   Returns      :
     float AvailableWater - Total water available for saturated flow

   Modifies     : void

   Comments     :
 *****************************************************************************/


/*****************************************************************************
  Function name: SnowMelt()

  Purpose      : Calculate snow accumulation and melt using an energy balance
                 approach for a two layer snow model

  Required     :
    int y                  - Row counter
    int x                  - Column counter
    int Dt                 - Model timestep (seconds)
    float Z                - Reference height (m)
    float Displacement     - Displacement height (m)
    float Z0               - Surface roughness (m)
    float BaseRa           - Aerodynamic resistance (uncorrected for
                             stability) (s/m)
    float AirDens          - Density of air (kg/m3)
    float EactAir          - Actual vapor pressure of air (Pa)
    float Lv               - Latent heat of vaporization (J/kg3)
    float ShortRad         - Net exchange of shortwave radiation (W/m2)
    float LongRadIn        - Incoming long wave radiation (W/m2)
    float Press            - Air pressure (Pa)
    float RainFall         - Amount of rain (m)
    float Snowfall         - Amount of snow (m)
    float Tair             - Air temperature (C)
    float Vpd              - Vapor pressure deficit (Pa)
    float Wind             - Wind speed (m/s)
    float *PackWater       - Liquid water content of snow pack
    float *SurfWater	   - Liquid water content of surface layer
    float *Swq             - Snow water equivalent at current pixel (m)
    float *VaporMassFlux;  - Mass flux of water vapor to or from the
                             intercepted snow (m)
    float *TPack           - Temperature of snow pack (C)
    float *TSurf           - Temperature of snow pack surface layer (C)
    float *MeltEnergy      - Energy used for melting and heating of snow pack
                             (W/m2)

  Returns      :
    float Outflow          - Amount of snowpack outflow (m)

  Modifies     :
    float *PackWater       - Liquid water content of snow pack
    float *SurfWater	   - Liquid water content of surface layer
    float *Swq             - Snow water equivalent at current pixel (m)
    float *VaporMassFlux;  - Mass flux of water vapor to or from the
                             intercepted snow (m)
    float *TPack           - Temperature of snow pack (C)
    float *TSurf           - Temperature of snow pack surface layer (C)
    float *MeltEnergy      - Energy used for melting and heating of snow pack
                             (W/m2)

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: CalcSnowPackEnergyBalance()

  Purpose      : Dummy function to make a direct call to
                 SnowEnergyBalance() possible.

  Required     :
    float TSurf - SnowPack surface temperature (C)
    other arguments required by SnowPackEnergyBalance()

  Returns      :
    float Qnet - Net energy exchange at the SnowPack snow surface (W/m^2)

  Modifies     : none

  Comments     : function is local to this module
*****************************************************************************/


/* -----------------------------------------------------------------------------
   InitChannel
   Reads stream and road files and builds the networks.
   -------------------------------------------------------------------------- */


/* -------------------------------------------------------------
   ChannelCulvertFlow
   computes outflow of channel/road network to a grid cell, if it
   contains a sink
   ------------------------------------------------------------- */


/* -------------------------------------------------------------
   ChannelCut
   computes necessary parameters for cell storage adjustment from
   channel/road dimensions
   ------------------------------------------------------------- */


/* -------------------------------------------------------------
   ChannelFraction
   This computes the (sub)surface flow fraction for a road
   ------------------------------------------------------------- */


/*****************************************************************************
   Function name: InitModelState()

   Purpose      : Initialize the state of the model using initial conditions
                  or a saved state from an earlier model run

   Required     :

   Returns      : void

   Modifies     :

   Comments :
     Initialize the model state, by reading the state variables from a series
     of files.  This allows restarts of the model from any timestep for which
     the model state is known.  These model states can be stored using the
     routine StoreModelState().  Timesteps at which to dump the model state
     can be specified in the file with dump information.

 *****************************************************************************/


/*****************************************************************************
  Function name: InitChannelRVeg()
  Purpose:	 This subroutine initiates the riparian extinction parameter for
             each channel segment
*****************************************************************************/


/*****************************************************************************
  Function name: CalcCanopyShading()
  Purpose:	 This subroutine calculates the shadow length
*****************************************************************************/


/*****************************************************************************
  Function name: CalcShadeDensity()
  Purpose:	 This subroutine calculates the effective shade density
  Note: The current program assumes same vegetation type with same height
        are plants along the riparaian zone.
        The program does not handle multiple vegeatation buffers with
        varying vegetation height. If needed, the code can be easily modified to
		account for this scenario.
******************************************************************************/


/*****************************************************************************
  Function name: CalcCanopySkyView()
  Purpose:	 This subroutine calculates the skyview factor above the riparaian
             vegetation
******************************************************************************/


/*****************************************************************************
  Function name: InitSnowMap()

  Purpose      : Initialize the snow information for each pixel in the basin

  Required     :
    MAPSIZE Map        - Size and location of the model area
    SNOWPIX ***SnowMap - Address of array with snow information

  Returns      : void

  Modifies     :
    Values stored at the locations pointed to by SnowMap

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: CreateMapFileBin()

  Purpose      : Open and close a new file.  If the file already exists it
                 will be overwritten.

  Required     :
    FileName  - Name of the new file

  Returns      : void

  Modifies     :

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: Read2DMatrixBin()

  Purpose      : Function to read a 2D array from a file.

  Required     :
    FileName   - name of input file
    Matrix     - address of array data into
    NumberType - code for number type (taken from HDF, see comments at the
                 beginning of InitFileIO.c for more detail)
    NY         - Number of rows
    NX         - Number of columns
    NDataSet   - number of the dataset to read, i.e. the first matrix in a
                 file is number 0, etc.
    Any remaining arguments are not used in straight binary

  Returns      : Number of elements read

  Modifies     : Matrix

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: Write2DMatrixBin()

  Purpose      : Function to write a 2D array to a file.  Data is appended to
                 the end of the file.

  Required     :
    FileName   - name of output file
    Matrix     - address of array containing matrix elements
    NumberType - code for number type (see comments at the
                 beginning of InitFileIO.c for more detail)
    NY         - Number of rows
    NX         - Number of columns

  Returns      : Number of elements written

  Modifies     :

  Comments     :
*****************************************************************************/


/*****************************************************************************
function  : IsStationLocation()
input     : Current Location, address of structure with station data, and
            pointer to int indicating which station is at current location
	    (if any)
output    : TRUE if the current location coincides with a station
            FALSE otherwise
modifies  : integer indicating which station is at current location
programmer: Bart Nijssen

This routine determines whether there is a station at the current location
*****************************************************************************/


/*****************************************************************************
  SnowStats()

  Calculate the statistics for SWE analysis (peak, peak date, melt out date).

  The intial values are set to zero in the function InitNewYear on very first
  timestep of a new water year.

  Dates were converted to unsigned int in format of YYYYMMDD.
*****************************************************************************/


/*****************************************************************************
  Function name: RootBrent()

  Purpose      : Calculate the surface temperature in the absence of snow

  Required     :
    int y                 - Row number of current pixel
    int x                 - Column number of current pixel
    float LowerBound      - Lower bound for root
    float UpperBound      - Upper bound for root
    float (*Function)(float Estimate, va_list ap)
    ...                   - Variable arguments
                            The number and order of arguments has to be
                            appropriate for the Function pointed to, since
                            the list of arguments after Nargs will be passed
                            on to Function.
                            See the appropriate Function for the correct
                            arguments.

  Returns      :
    float b               - Effective surface temperature (C)

  Modifies     : none

  Comments     :
*****************************************************************************/


/********************************************************************************
Function Name: InitSoilTable()

Purpose      : Initialize the soil lookup table
Processes most of the following section in InFileName:
[SOILS]

Required     :
SOILTABLE **SType - Pointer to lookup table
LISTPTR Input     - Pointer to linked list with input info
LAYER *Soil       - Pointer to structure with soil layer information

Returns      : Number of soil layers

Modifies     : SoilTable and Soil

Comments     :
********************************************************************************/


/********************************************************************************
Function Name: InitVegTable()

Purpose      : Initialize the vegetation lookup table
Processes most of the following section in the input file:
[VEGETATION]

Required     :
VEGTABLE **VType - Pointer to lookup table
LISTPTR Input    - Pointer to linked list with input info
LAYER *Veg       - Pointer to structure with veg layer information

Returns      : Number of vegetation types

Modifies     : VegTable and Veg

Comments     :
********************************************************************************/


/*****************************************************************************
   Avalanche()

   Sources:
   Bernhardt, M., and K. Schulz (2010), SnowSlide: A simple routine for calculating
   gravitational snow transport, Geophys. Res. Lett., 37, L11502,
   doi:10.1029/2010GL043086.

   This routine follows Bernhardt, M., and K. Schulz (2010) in calculating gravitational
   redistribution of snow. Routing algorithms are similar to those used in
   RouteSubsurface.c. The local gradient is taken to be equal to the slope of the land
   surface. The slope is not currently calculated based on surface elevation of
   the snowpack.

   Set the gradient with pixels that are outside tha basin to zero.  This
   ensures that there is no flux of water across the basin boundary.

   WORK IN PROGRESS:
   Calculate slope based on Ice and Snow on top of topography.
   Transfer Cold Content of Snowpack with Mass.
 *****************************************************************************/


/*****************************************************************************
  ResetAggregate()

  Set all the area averages to zero
*****************************************************************************/


/*****************************************************************************
  Aggregate()

  Calculate the average values for the different fluxes and state variables
  over the basin.
  In the current implementation the local radiation
  elements are not stored for the entire area.  Therefore these components
  are aggregated in AggregateRadiation() inside MassEnergyBalance().

  The aggregated values are set to zero in the function RestAggregate,
  which is executed at the beginning of each time step.
*****************************************************************************/


/*****************************************************************************
  Function name: StabilityCorrection()

  Purpose      : Calculate atmospheric stability correction for non-neutral
                 conditions

  Required     :
    float Z          - Reference height (m)
    float d          - Displacement height (m)
    float TSurf      - Surface temperature (C)
    float Tair       - Air temperature (C)
    float Wind       - Wind speed (m/s)
    float Z0         - Roughness length (m)

  Returns      :
    float Correction - Multiplier for aerodynamic resistance

  Modifies     : None

  Comments     :
*****************************************************************************/


/*****************************************************************************
Function name: WaterTableDepth()

Purpose      :   This function calculates the depth of the water table
below the ground surface, based on the amount of soil
moisture in the root zone layers.

Required     :
int NRootLayers  - Number of soil layers
float TotalDepth - Total depth of the soil profile (m)
float *RootDepth - Depth of each of the soil layers (m)
float *Porosity  - Porosity of each soil layer
float *FCap      - Field capacity of each soil layer
float *Adjust    - Correction for each layer for loss of soil storage
due to channel/road-cut.  Multiplied with RootDepth
to give the layer thickness for use in calculating
soil moisture

Returns      :
float TableDepth - Depth of the water table below the soil surface

Modifies     :
float *Moist - Amount of soil moisture in each layer

Comments     :
Since no unsaturated flow is allowed to occur when the moisture content
is below the field capacity, and because lateral saturated flow is the
only mechanism by which water can disappear from the soil below the
deepest root layer, the soil moisture content in the soil below the
deepest root layer can never fall below field capacity.  The water
immediately above the water table is assumed to be at field capacity.

Changes have been made to account for the potential loss of soil storage
in a grid cell due to a road-cut or channel.
*****************************************************************************/


/*****************************************************************************
   Function name: MassEnergyBalance()

   Purpose      : Calculate mass and energy balance

   Required     :

   Returns      : void

   Modifies     :

   Comments     :

   Reference    :
     Epema, G.F. and H.T. Riezbos, 1983, Fall Velocity of waterdrops at different
 heights as a factor influencing erosivity of simulated rain. Rainfall simulation,
 Runoff and Soil Erosion. Catena suppl. 4, Braunschweig. Jan de Ploey (Ed), 1-17.

   Laws, J.o., and D.A. Parsons, 1943, the relation of raindrop size to intensity.
 Trans. Am. Geophys. Union, 24: 452-460.

 *****************************************************************************/


/*****************************************************************************
  Function name: InitUnitHydrograph()

  Purpose      :

  Required     :

  Returns      : void

  Modifies     :

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: MaxRoadInfiltration()

*****************************************************************************/


/*****************************************************************************
  Function name: LapseT()

  Purpose      : Lapse temperature with elevation

  Required     :
    float Temp       - Air temperature at FromElev elevation (C)
    float FromElev   - Elevation to lapse from (m)
    float ToElev     - Elevation to lapse to (m)
    float LapseRate  - Lapse rate in (m/m)

  Returns      :
    float LapsedTemp - Air temperature at ToElev elevation (C)

  Modifies     : None

  Comments     :
*****************************************************************************/


/*****************************************************************************
  Function name: LapsePrecip

  Purpose      : Lapse precipitation with elevation

  Required     :
    float Precip       - Precipitation at FromElev (m/timestep)
    float FromElev     - Elevation to lapse from (m)
    float ToElev       - Elevation to lapse to (m)

  Returns      :
    float LapsedPrecip - Precipitation at ToElev (m/timestep)

  Modifies     : None

  Comments     : Used to lapse precip with elevation.
*****************************************************************************/