Пример #1
0
/*****************************************************************************
  ReadRadarMap()
*****************************************************************************/
void ReadRadarMap(DATE * Current, DATE * StartRadar, int Dt, MAPSIZE * Radar,
		  RADARPIX ** RadarMap, char *FileName)
{
  const char *Routine = "ReadRadarMap";
  int i;			/* counter */
  int x;			/* counter */
  int y;			/* counter */
  int RadarStep;		/* Location of current timestep in radarfile */
  int NumberType;		/* number type */
  void *Array;

  if (DEBUG)
    printf("Reading precipitation radar data from file: %s\n", FileName);

  NumberType = NC_FLOAT;

  if (!(Array = (float *) calloc(Radar->NY * Radar->NX,
				 SizeOfNumberType(NumberType))))
    ReportError((char *) Routine, 1);

  RadarStep = NumberOfSteps(StartRadar, Current, Dt);

  /* Read the precipitation */
  Read2DMatrix(FileName, Array, NumberType, Radar->NY, Radar->NX, RadarStep);

  for (y = 0, i = 0; y < Radar->NY; y++)
    for (x = 0; x < Radar->NX; x++, i++)
      RadarMap[y][x].Precip = ((float *) Array)[i];

  free(Array);
}
Пример #2
0
/*******************************************************************************
  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
*******************************************************************************/
void InitImageDump(LISTPTR Input, int Dt, MAPSIZE * Map, int MaxSoilLayers,
  int MaxVegLayers, char *Path, int NMaps, int NImages,
  MAPDUMP ** DMap)
{
  char *Routine = "InitImageDump";
  DATE End;			/* End of low resolution map dump period */
  DATE Start;			/* Start of low resolution map dump period */
  int i;			/* counter */
  int j;			/* counter */
  int Interval;			/* Interval between low resolution map dumps */
  int MaxLayers;		/* Maximum number of layers allowed for this
                   variable */
  char KeyName[image_lower + 1][BUFSIZE + 1];
  char *KeyStr[] = {
    "IMAGE VARIABLE",
    "IMAGE LAYER",
    "IMAGE START",
    "IMAGE END",
    "IMAGE INTERVAL",
    "IMAGE UPPER LIMIT",
    "IMAGE LOWER LIMIT"
  };
  char *SectionName = "OUTPUT";
  char VarStr[image_lower + 1][BUFSIZE + 1];
  float tmpInterval;

  for (i = NMaps - NImages; i < NMaps; i++) {

    /* Read the key-entry pairs from the input file */
    for (j = 0; j <= image_lower; j++) {
      sprintf(KeyName[j], "%s %d", KeyStr[j], i - (NMaps - NImages) + 1);
      GetInitString(SectionName, KeyName[j], "", VarStr[j],
        (unsigned long)BUFSIZE, Input);
    }

    /* Assign the entries to the appropriate variables */
    if (!CopyInt(&((*DMap)[i].ID), VarStr[image_variable], 1))
      ReportError(KeyName[image_variable], 51);

    if (!IsValidID((*DMap)[i].ID))
      ReportError("Input Options File", 19);

    if (IsMultiLayer((*DMap)[i].ID)) {
      MaxLayers = GetVarNLayers((*DMap)[i].ID, MaxSoilLayers, MaxVegLayers);
      if (!CopyInt(&((*DMap)[i].Layer), VarStr[image_layer], 1))
        ReportError(KeyName[image_layer], 51);
      if ((*DMap)[i].Layer < 1 || (*DMap)[i].Layer > MaxLayers)
        ReportError("Input Options File", 20);
    }
    else
      (*DMap)[i].Layer = 1;

    (*DMap)[i].Resolution = IMAGE_OUTPUT;

    strncpy((*DMap)[i].FileName, Path, BUFSIZE);
    GetVarAttr(&((*DMap)[i]));
    (*DMap)[i].NumberType = NC_BYTE;
    strcpy((*DMap)[i].Format, "%d");

    CreateMapFile((*DMap)[i].FileName, (*DMap)[i].FileLabel, Map);

    if (!SScanDate(VarStr[image_start], &Start))
      ReportError(KeyName[image_start], 51);

    if (!SScanDate(VarStr[image_end], &End))
      ReportError(KeyName[image_end], 51);

    if (!CopyFloat(&tmpInterval, VarStr[image_interval], 1))
      ReportError(KeyName[image_interval], 51);
    Interval = SECPHOUR * tmpInterval;

    if (Interval % Dt != 0 || Interval <= 0)
      ReportError("Input Options File", 24);

    if (((*DMap)[i].N = NumberOfSteps(&Start, &End, Interval)) < 1)
      ReportError("Input Options File", 25);

    if (!((*DMap)[i].DumpDate = (DATE *)calloc((*DMap)[i].N, sizeof(DATE))))
      ReportError(Routine, 1);

    CopyDate(&((*DMap)[i].DumpDate[0]), &Start);

    for (j = 1; j < (*DMap)[i].N; j++)
      (*DMap)[i].DumpDate[j] =
      NextDate(&((*DMap)[i].DumpDate[j - 1]), Interval);

    if (!CopyFloat(&((*DMap)[i].MaxVal), VarStr[image_upper], 1))
      ReportError(KeyName[image_upper], 51);

    if (!CopyFloat(&((*DMap)[i].MinVal), VarStr[image_lower], 1))
      ReportError(KeyName[image_lower], 51);
  }
}
Пример #3
0
int InitTime(TIMESTRUCT * Time, DATE * Start, DATE * End, DATE * StartRadar,
	     DATE * StartMM5, int Dt)
{
  const char *Routine = "InitTime";
  int tmpsecond;

  Time->Dt = Dt;		/* timestep in seconds */

  /* Just to be sure, recalculate the Julian and JDay fields of all the dates */
  if (Start != NULL) {
    CopyDate(&(Time->Start), Start);
    Time->Start.JDay = DayOfYear(Time->Start.Year, Time->Start.Month,
				 Time->Start.Day);
    Time->Start.Julian = GregorianToJulianDay(Time->Start.Year,
					      Time->Start.Month,
					      Time->Start.Day,
					      Time->Start.Hour,
					      Time->Start.Min, Time->Start.Sec);
    CopyDate(&(Time->Current), &(Time->Start));
  }

  if (End != NULL) {
    CopyDate(&(Time->End), End);
    Time->End.JDay = DayOfYear(Time->End.Year, Time->End.Month, Time->End.Day);
    Time->End.Julian = GregorianToJulianDay(Time->End.Year, Time->End.Month,
					    Time->End.Day, Time->End.Hour,
					    Time->End.Min, Time->End.Sec);
  }
  if (StartRadar != NULL) {
    CopyDate(&(Time->StartRadar), StartRadar);
    Time->StartRadar.JDay =
      DayOfYear(Time->StartRadar.Year, Time->StartRadar.Month,
		Time->StartRadar.Day);
    Time->StartRadar.Julian =
      GregorianToJulianDay(Time->StartRadar.Year, Time->StartRadar.Month,
			   Time->StartRadar.Day, Time->StartRadar.Hour,
			   Time->StartRadar.Min, Time->StartRadar.Sec);
  }
  if (StartMM5 != NULL) {
    CopyDate(&(Time->StartMM5), StartMM5);
    Time->StartMM5.JDay =
      DayOfYear(Time->StartMM5.Year, Time->StartMM5.Month, Time->StartMM5.Day);
    Time->StartMM5.Julian =
      GregorianToJulianDay(Time->StartMM5.Year, Time->StartMM5.Month,
			   Time->StartMM5.Day, Time->StartMM5.Hour,
			   Time->StartMM5.Min, Time->StartMM5.Sec);
  }

  if (Start != NULL && End != NULL) {
    if (After(&(Time->Start), &(Time->End)))
      return FALSE;
    Time->Step = 0;
    Time->NDaySteps = SECPDAY / Time->Dt;
    if ((SECPDAY - Time->NDaySteps * Time->Dt) != 0)
      ReportError((char *) Routine, 7);
    /* the 0.5 in the next line is because Julian day is measured from midday,
       and  we want since midnight */
    tmpsecond = Round(((Time->Start.Julian - 0.5) -
		       floor(Time->Start.Julian - 0.5)) * SECPDAY);
    Time->DayStep = tmpsecond / Time->Dt;
    /* The following line insures that the first timestep of the day would
       coincide with midnight */
    if (tmpsecond - Time->DayStep * Time->Dt != 0)
      ReportError((char *) Routine, 9);
    Time->NTotalSteps = NumberOfSteps(&(Time->Start), &(Time->End), Time->Dt);
    if (Time->NTotalSteps == FAIL)
      return FALSE;
  }

  return TRUE;
}
Пример #4
0
/*****************************************************************************
  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
    RADCLASSPIX **RadMap     - Structure with radiation data for each pixel
    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
*****************************************************************************/
void InitNewStep(INPUTFILES *InFiles, MAPSIZE *Map, TIMESTRUCT *Time,
		 int NSoilLayers, OPTIONSTRUCT *Options, int NStats,
		 METLOCATION *Stat, char *RadarFileName, MAPSIZE *Radar,
		 RADARPIX **RadarMap, SOLARGEOMETRY *SolarGeo, 
		 TOPOPIX **TopoMap, RADCLASSPIX **RadMap, SOILPIX **SoilMap,
		 float ***MM5Input, float ***WindModel, MAPSIZE *MM5Map)
{
  const char *Routine = "InitNewStep";
  int i;			/* counter */
  int j;			/* counter */
  int x;			/* counter */
  int y;			/* counter */
  int NumberType;		/* number type in MM5 input */
  int Step;			/* Step in the MM5 Input */
  float *Array = NULL;
  int MM5Y, MM5X;

  /* Calculate variables related to the position of the sun above the
     horizon, this is only necessary if shading is TRUE */

  SolarHour(SolarGeo->Latitude,
	    (Time->DayStep + 1) * ((float) Time->Dt) / SECPHOUR,
	    ((float) Time->Dt) / SECPHOUR, SolarGeo->NoonHour,
	    SolarGeo->Declination, SolarGeo->Sunrise, SolarGeo->Sunset,
	    SolarGeo->TimeAdjustment, SolarGeo->SunEarthDistance,
	    &(SolarGeo->SineSolarAltitude), &(SolarGeo->DayLight),
	    &(SolarGeo->SolarTimeStep), &(SolarGeo->SunMax),
	    &(SolarGeo->SolarAzimuth));

/*printf("SunMax is %f\n",SolarGeo->SunMax);*/
  if (Options->MM5 == TRUE) {

    /* Read the data from the MM5 files */

    if (!(Array = (float *) calloc(MM5Map->NY * MM5Map->NX, sizeof(float))))
      ReportError((char *) Routine, 1);
    NumberType = NC_FLOAT;

    Step = NumberOfSteps(&(Time->StartMM5), &(Time->Current), Time->Dt);

    Read2DMatrix(InFiles->MM5Temp, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_temperature - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }

    Read2DMatrix(InFiles->MM5Humidity, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);

    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_humidity - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }

    Read2DMatrix(InFiles->MM5Wind, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_wind - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }

    Read2DMatrix(InFiles->MM5ShortWave, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_shortwave - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }

    Read2DMatrix(InFiles->MM5LongWave, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_longwave - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }

    Read2DMatrix(InFiles->MM5Precipitation, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_precip - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
	if (MM5Input[MM5_precip - 1][y][x] < 0.0) {
	  printf("Warning: MM5 precip is less than zero %f\n",
		 MM5Input[MM5_precip - 1][y][x]);
	  MM5Input[MM5_precip - 1][y][x] = 0.0;
	}
      }
    Read2DMatrix(InFiles->MM5Terrain, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_terrain - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }
    Read2DMatrix(InFiles->MM5Lapse, Array, NumberType, MM5Map->NY,
		 MM5Map->NX, Step);
    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++) {
	MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	MM5Input[MM5_lapse - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
      }

    if (Options->HeatFlux == TRUE) {

      for (i = 0, j = MM5_lapse; i < NSoilLayers; i++, j++) {
	Read2DMatrix(InFiles->MM5SoilTemp[i], Array, NumberType, MM5Map->NY,
		     MM5Map->NX, Step);
	for (y = 0; y < Map->NY; y++)
	  for (x = 0; x < Map->NX; x++) {
	    MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY);
	    MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY);
	    MM5Input[j][y][x] = Array[MM5Y * MM5Map->NX + MM5X];
	  }
      }
    }
    free(Array);
  }
/*end if MM5*/

  /* if the flow gradient is based on the water table, recalculate the water
     table gradients.  Flow directions are now calculated in RouteSubSurface*/
  if (Options->FlowGradient == WATERTABLE) {
    /* Calculate the WaterLevel, i.e. the height of the water table above 
       some datum */
    for (y = 0; y < Map->NY; y++) {
      for (x = 0; x < Map->NX; x++) {
	if (INBASIN(TopoMap[y][x].Mask)) {
	  SoilMap[y][x].WaterLevel =
	    TopoMap[y][x].Dem - SoilMap[y][x].TableDepth;
	}
      }
    }
/*     HeadSlopeAspect(Map, TopoMap, SoilMap); */
  }

  if ((Options->MM5 == TRUE && Options->QPF == TRUE) || Options->MM5 == FALSE)
    GetMetData(Options, Time, NSoilLayers, NStats, SolarGeo->SunMax, Stat,
	       Radar, RadarMap, RadarFileName);
}