int main(int argc, char **argv) { float *Hydrograph = NULL; float ***MM5Input = NULL; float **PrecipLapseMap = NULL; float **PrismMap = NULL; unsigned char ***ShadowMap = NULL; float **SkyViewMap = NULL; float ***WindModel = NULL; int MaxStreamID, MaxRoadID; float SedDiams[NSEDSIZES]; /* Sediment particle diameters (mm) */ clock_t start, finish1; double runtime = 0.0; int t = 0; float roadarea; time_t tloc; int flag; int i; int j; int x; /* row counter */ int y; /* column counter */ int shade_offset; /* a fast way of handling arraay position given the number of mm5 input options */ int NStats; /* Number of meteorological stations */ uchar ***MetWeights = NULL; /* 3D array with weights for interpolating meteorological variables between the stations */ int NGraphics; /* number of graphics for X11 */ int *which_graphics; /* which graphics for X11 */ char buffer[32]; AGGREGATED Total = { /* Total or average value of a variable over the entire basin */ {0.0, NULL, NULL, NULL, NULL, 0.0}, /* EVAPPIX */ {0.0, 0.0, 0.0, 0.0, 0.0, NULL, NULL, 0.0, 0, 0.0}, /* PRECIPPIX */ {{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, 0.0, 0.0, 0.0}, /* PIXRAD */ {0.0, 0.0}, /* RADCLASSPIX */ {0.0, 0.0, 0, NULL, NULL, 0.0, 0, 0.0, 0.0, 0.0, 0.0, NULL, NULL, NULL, NULL, NULL, NULL, 0.0}, /* ROADSTRUCT*/ {0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, /* SNOWPIX */ {0, 0.0, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, /*SOILPIX */ { 0.0, 0.0, 0.0, 0.0, 0.0}, /*SEDPIX */ { 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, /*FINEPIX */ 0.0, 0.0, 0.0, 0.0, 0.0, 0l, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; CHANNEL ChannelData = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; DUMPSTRUCT Dump; EVAPPIX **EvapMap = NULL; INPUTFILES InFiles; LAYER Soil; LAYER Veg; LISTPTR Input = NULL; /* Linked list with input strings */ MAPSIZE Map; /* Size and location of model area */ MAPSIZE Radar; /* Size and location of area covered by precipitation radar */ MAPSIZE MM5Map; /* Size and location of area covered by MM5 input files */ METLOCATION *Stat = NULL; OPTIONSTRUCT Options; /* Structure with information which program options to follow */ PIXMET LocalMet; /* Meteorological conditions for current pixel */ FINEPIX ***FineMap = NULL; PRECIPPIX **PrecipMap = NULL; RADARPIX **RadarMap = NULL; RADCLASSPIX **RadMap = NULL; PIXRAD **RadiationMap = NULL; ROADSTRUCT **Network = NULL; /* 2D Array with channel information for each pixel */ SNOWPIX **SnowMap = NULL; MET_MAP_PIX **MetMap = NULL; SNOWTABLE *SnowAlbedo = NULL; SOILPIX **SoilMap = NULL; SEDPIX **SedMap = NULL; SOILTABLE *SType = NULL; SEDTABLE *SedType = NULL; SOLARGEOMETRY SolarGeo; /* Geometry of Sun-Earth system (needed for INLINE radiation calculations */ TIMESTRUCT Time; TOPOPIX **TopoMap = NULL; UNITHYDR **UnitHydrograph = NULL; UNITHYDRINFO HydrographInfo; /* Information about unit hydrograph */ VEGPIX **VegMap = NULL; VEGTABLE *VType = NULL; WATERBALANCE Mass = /* parameter for mass balance calculations */ { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /***************************************************************************** Initialization Procedures *****************************************************************************/ if (argc != 2) { fprintf(stderr, "\nUsage: %s inputfile\n\n", argv[0]); fprintf(stderr, "DHSVM uses two output streams: \n"); fprintf(stderr, "Standard Out, for the majority of output \n"); fprintf(stderr, "Standard Error, for the final mass balance \n"); fprintf(stderr, "\nTo pipe output correctly to files: \n"); fprintf(stderr, "(cmd > f1) >& f2 \n"); fprintf(stderr, "where f1 is stdout_file and f2 is stderror_file\n"); exit(EXIT_FAILURE); } sprintf(commandline, "%s %s", argv[0], argv[1]); printf("%s \n", commandline); fprintf(stderr, "%s \n", commandline); strcpy(InFiles.Const, argv[1]); printf("\nRunning DHSVM %s\n", version); printf("\nSTARTING INITIALIZATION PROCEDURES\n\n"); /* Start recording time */ start = clock(); ReadInitFile(InFiles.Const, &Input); InitConstants(Input, &Options, &Map, &SolarGeo, &Time); InitFileIO(Options.FileFormat); InitTables(Time.NDaySteps, Input, &Options, &SType, &Soil, &VType, &Veg, &SnowAlbedo); InitTerrainMaps(Input, &Options, &Map, &Soil, &TopoMap, &SoilMap, &VegMap); CheckOut(Options.CanopyRadAtt, Veg, Soil, VType, SType, &Map, TopoMap, VegMap, SoilMap); if (Options.HasNetwork) InitChannel(Input, &Map, Time.Dt, &ChannelData, SoilMap, &MaxStreamID, &MaxRoadID, &Options); else if (Options.Extent != POINT) InitUnitHydrograph(Input, &Map, TopoMap, &UnitHydrograph, &Hydrograph, &HydrographInfo); InitNetwork(Map.NY, Map.NX, Map.DX, Map.DY, TopoMap, SoilMap, VegMap, VType, &Network, &ChannelData, Veg, &Options); InitMetSources(Input, &Options, &Map, Soil.MaxLayers, &Time, &InFiles, &NStats, &Stat, &Radar, &MM5Map); /* the following piece of code is for the UW PRISM project */ /* for real-time verification of SWE at Snotel sites */ /* Other users, set OPTION.SNOTEL to FALSE, or use TRUE with caution */ if (Options.Snotel == TRUE && Options.Outside == FALSE) { printf ("Warning: All met stations locations are being set to the vegetation class GLACIER\n"); printf ("Warning: This requires that you have such a vegetation class in your vegetation table\n"); printf("To disable this feature set Snotel OPTION to FALSE\n"); for (i = 0; i < NStats; i++) { printf("veg type for station %d is %d ", i, VegMap[Stat[i].Loc.N][Stat[i].Loc.E].Veg); for (j = 0; j < Veg.NTypes; j++) { if (VType[j].Index == GLACIER) { VegMap[Stat[i].Loc.N][Stat[i].Loc.E].Veg = j; break; } } if (j == Veg.NTypes) { /* glacier class not found */ ReportError("MainDHSVM", 62); } printf("setting to glacier type (assumed bare class): %d\n", j); } } InitMetMaps(Time.NDaySteps, &Map, &Radar, &Options, InFiles.WindMapPath, InFiles.PrecipLapseFile, &PrecipLapseMap, &PrismMap, &ShadowMap, &SkyViewMap, &EvapMap, &PrecipMap, &RadarMap, &RadMap, SoilMap, &Soil, VegMap, &Veg, TopoMap, &MM5Input, &WindModel); InitInterpolationWeights(&Map, &Options, TopoMap, &MetWeights, Stat, NStats); InitDump(Input, &Options, &Map, Soil.MaxLayers, Veg.MaxLayers, Time.Dt, TopoMap, &Dump, &NGraphics, &which_graphics); if (Options.HasNetwork == TRUE) { InitChannelDump(&Options, &ChannelData, Dump.Path); ReadChannelState(Dump.InitStatePath, &(Time.Start), ChannelData.streams); } InitSnowMap(&Map, &SnowMap); InitAggregated(Veg.MaxLayers, Soil.MaxLayers, &Total); InitModelState(&(Time.Start), &Map, &Options, PrecipMap, SnowMap, SoilMap, Soil, SType, VegMap, Veg, VType, Dump.InitStatePath, SnowAlbedo, TopoMap, Network, &HydrographInfo, Hydrograph); InitNewMonth(&Time, &Options, &Map, TopoMap, PrismMap, ShadowMap, RadMap, &InFiles, Veg.NTypes, VType, NStats, Stat, Dump.InitStatePath); InitNewDay(Time.Current.JDay, &SolarGeo); if (NGraphics > 0) { printf("Initialzing X11 display and graphics \n"); InitXGraphics(argc, argv, Map.NY, Map.NX, NGraphics, &MetMap); } shade_offset = FALSE; if (Options.Shading == TRUE) shade_offset = TRUE; /* Done with initialization, delete the list with input strings */ DeleteList(Input); /***************************************************************************** Sediment Initialization Procedures *****************************************************************************/ if(Options.Sediment) { time (&tloc); srand (tloc); /* Randomize Random Generator */ /* Commenting the line above and uncommenting the line below allows for the comparison of scenarios. */ /* srand48 (0); */ printf("\nSTARTING SEDIMENT INITIALIZATION PROCEDURES\n\n"); ReadInitFile(Options.SedFile, &Input); InitParameters(Input, &Options, &Map, &Network, &ChannelData, TopoMap, &Time, SedDiams); InitSedimentTables(Time.NDaySteps, Input, &SedType, &SType, &VType, &Soil, &Veg); InitFineMaps(Input, &Options, &Map, &Soil, &TopoMap, &SoilMap, &FineMap); if (Options.HasNetwork){ printf("Initializing channel sediment\n\n"); InitChannelSedimentDump(&ChannelData, Dump.Path, Options.ChannelRouting); InitChannelSediment(ChannelData.streams, &Total); InitChannelSediment(ChannelData.roads, &Total); } InitSedMap( &Map, &SedMap); /* Done with initialization, delete the list with input strings */ DeleteList(Input); } /* setup for mass balance calculations */ Aggregate(&Map, &Options, TopoMap, &Soil, &Veg, VegMap, EvapMap, PrecipMap, RadMap, SnowMap, SoilMap, &Total, VType, Network, SedMap, FineMap, &ChannelData, &roadarea); Mass.StartWaterStorage = Total.Soil.IExcess + Total.CanopyWater + Total.SoilWater + Total.Snow.Swq + Total.Soil.SatFlow; Mass.OldWaterStorage = Mass.StartWaterStorage; if (Options.Sediment) { Mass.StartChannelSedimentStorage = Total.ChannelSedimentStorage; Mass.LastChannelSedimentStorage = Mass.StartChannelSedimentStorage; } /* computes the number of grid cell contributing to one segment */ if (Options.StreamTemp) Init_segment_ncell(TopoMap, ChannelData.stream_map, Map.NY, Map.NX, ChannelData.streams); /***************************************************************************** Perform Calculations *****************************************************************************/ while (Before(&(Time.Current), &(Time.End)) || IsEqualTime(&(Time.Current), &(Time.End))) { ResetAggregate(&Soil, &Veg, &Total, &Options); if (IsNewMonth(&(Time.Current), Time.Dt)) InitNewMonth(&Time, &Options, &Map, TopoMap, PrismMap, ShadowMap, RadMap, &InFiles, Veg.NTypes, VType, NStats, Stat, Dump.InitStatePath); if (IsNewDay(Time.DayStep)) { InitNewDay(Time.Current.JDay, &SolarGeo); PrintDate(&(Time.Current), stdout); printf("\n"); } /* determine surface erosion and routing scheme */ SedimentFlag(&Options, &Time); InitNewStep(&InFiles, &Map, &Time, Soil.MaxLayers, &Options, NStats, Stat, InFiles.RadarFile, &Radar, RadarMap, &SolarGeo, TopoMap, RadMap, SoilMap, MM5Input, WindModel, &MM5Map); /* initialize channel/road networks for time step */ if (Options.HasNetwork) { channel_step_initialize_network(ChannelData.streams); channel_step_initialize_network(ChannelData.roads); } for (y = 0; y < Map.NY; y++) { for (x = 0; x < Map.NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { if (Options.Shading) LocalMet = MakeLocalMetData(y, x, &Map, Time.DayStep, &Options, NStats, Stat, MetWeights[y][x], TopoMap[y][x].Dem, &(RadMap[y][x]), &(PrecipMap[y][x]), &Radar, RadarMap, PrismMap, &(SnowMap[y][x]), SnowAlbedo, MM5Input, WindModel, PrecipLapseMap, &MetMap, NGraphics, Time.Current.Month, SkyViewMap[y][x], ShadowMap[Time.DayStep][y][x], SolarGeo.SunMax, SolarGeo.SineSolarAltitude); else LocalMet = MakeLocalMetData(y, x, &Map, Time.DayStep, &Options, NStats, Stat, MetWeights[y][x], TopoMap[y][x].Dem, &(RadMap[y][x]), &(PrecipMap[y][x]), &Radar, RadarMap, PrismMap, &(SnowMap[y][x]), SnowAlbedo, MM5Input, WindModel, PrecipLapseMap, &MetMap, NGraphics, Time.Current.Month, 0.0, 0.0, SolarGeo.SunMax, SolarGeo.SineSolarAltitude); for (i = 0; i < Soil.MaxLayers; i++) { if (Options.HeatFlux == TRUE) { if (Options.MM5 == TRUE) SoilMap[y][x].Temp[i] = MM5Input[shade_offset + i + N_MM5_MAPS][y][x]; else SoilMap[y][x].Temp[i] = Stat[0].Data.Tsoil[i]; } else SoilMap[y][x].Temp[i] = LocalMet.Tair; } MassEnergyBalance(&Options, y, x, SolarGeo.SineSolarAltitude, Map.DX, Map.DY, Time.Dt, Options.HeatFlux, Options.CanopyRadAtt, Options.RoadRouting, Options.Infiltration, Veg.MaxLayers, &LocalMet, &(Network[y][x]), &(PrecipMap[y][x]), &(VType[VegMap[y][x].Veg-1]), &(VegMap[y][x]), &(SType[SoilMap[y][x].Soil-1]), &(SoilMap[y][x]), &(SnowMap[y][x]), &(EvapMap[y][x]), &(Total.Rad), &ChannelData, SkyViewMap); PrecipMap[y][x].SumPrecip += PrecipMap[y][x].Precip; } } } /* Average all RBM inputs over each segment */ if (Options.StreamTemp) { channel_grid_avg(ChannelData.streams); } #ifndef SNOW_ONLY /* set sediment inflows to zero - they are incremented elsewhere */ if ((Options.HasNetwork) && (Options.Sediment)){ InitChannelSedInflow(ChannelData.streams); InitChannelSedInflow(ChannelData.roads); } RouteSubSurface(Time.Dt, &Map, TopoMap, VType, VegMap, Network, SType, SoilMap, &ChannelData, &Time, &Options, Dump.Path, SedMap, FineMap, SedType, MaxStreamID, SnowMap); if (Options.HasNetwork) RouteChannel(&ChannelData, &Time, &Map, TopoMap, SoilMap, &Total, &Options, Network, SType, PrecipMap, SedMap, LocalMet.Tair, LocalMet.Rh, SedDiams); /* Sediment Routing in Channel and output to sediment files */ if ((Options.HasNetwork) && (Options.Sediment)){ SPrintDate(&(Time.Current), buffer); flag = IsEqualTime(&(Time.Current), &(Time.Start)); if (Options.ChannelRouting){ if (ChannelData.roads != NULL) { RouteChannelSediment(ChannelData.roads, Time, &Dump, &Total, SedDiams); channel_save_sed_outflow_text(buffer, ChannelData.roads, ChannelData.sedroadout, ChannelData.sedroadflowout, flag); RouteCulvertSediment(&ChannelData, &Map, TopoMap, SedMap, &Total, SedDiams); } RouteChannelSediment(ChannelData.streams, Time, &Dump, &Total, SedDiams); channel_save_sed_outflow_text(buffer, ChannelData.streams, ChannelData.sedstreamout, ChannelData.sedstreamflowout, flag); } else { if (ChannelData.roads != NULL) { channel_save_sed_inflow_text(buffer, ChannelData.roads, ChannelData.sedroadinflow, SedDiams,flag); } channel_save_sed_inflow_text(buffer, ChannelData.streams, ChannelData.sedstreaminflow, SedDiams,flag); } SaveChannelSedInflow(ChannelData.roads, &Total); SaveChannelSedInflow(ChannelData.streams, &Total); } if (Options.Extent == BASIN) RouteSurface(&Map, &Time, TopoMap, SoilMap, &Options, UnitHydrograph, &HydrographInfo, Hydrograph, &Dump, VegMap, VType, SType, &ChannelData, SedMap, PrecipMap, SedType, LocalMet.Tair, LocalMet.Rh, SedDiams); #endif if (NGraphics > 0) draw(&(Time.Current), IsEqualTime(&(Time.Current), &(Time.Start)), Time.DayStep, &Map, NGraphics, which_graphics, VType, SType, SnowMap, SoilMap, SedMap, FineMap, VegMap, TopoMap, PrecipMap, PrismMap, SkyViewMap, ShadowMap, EvapMap, RadMap, MetMap, Network, &Options); Aggregate(&Map, &Options, TopoMap, &Soil, &Veg, VegMap, EvapMap, PrecipMap, RadMap, SnowMap, SoilMap, &Total, VType, Network, SedMap, FineMap, &ChannelData, &roadarea); MassBalance(&(Time.Current), &(Dump.Balance), &(Dump.SedBalance), &Total, &Mass, &Options); ExecDump(&Map, &(Time.Current), &(Time.Start), &Options, &Dump, TopoMap, EvapMap, RadiationMap, PrecipMap, RadMap, SnowMap, MetMap, VegMap, &Veg, SoilMap, SedMap, Network, &ChannelData, FineMap, &Soil, &Total, &HydrographInfo,Hydrograph); IncreaseTime(&Time); t += 1; } ExecDump(&Map, &(Time.Current), &(Time.Start), &Options, &Dump, TopoMap, EvapMap, RadiationMap, PrecipMap, RadMap, SnowMap, MetMap, VegMap, &Veg, SoilMap, SedMap, Network, &ChannelData, FineMap, &Soil, &Total, &HydrographInfo, Hydrograph); FinalMassBalance(&(Dump.FinalBalance), &Total, &Mass, &Options, roadarea); /*printf("\nSTARTING CLEANUP\n\n"); cleanup(&Dump, &ChannelData, &Options);*/ printf("\nEND OF MODEL RUN\n\n"); /* record the run time at the end of each time loop */ finish1 = clock (); runtime = (finish1-start)/CLOCKS_PER_SEC; printf("***********************************************************************************"); printf("\nRuntime Summary:\n"); printf("%6.2f hours elapsed for the simulation period of %d hours (%.1f days) \n", runtime/3600, t*Time.Dt/3600, (float)t*Time.Dt/3600/24); return EXIT_SUCCESS; }
int main(int argc, char **argv) { float *Hydrograph = NULL; float ***MM5Input = NULL; float **PrecipLapseMap = NULL; float **PrismMap = NULL; unsigned char ***ShadowMap = NULL; float **SkyViewMap = NULL; float ***WindModel = NULL; /* Glacier Model Variable */ double dt_year; double year_min; double year_max; int MaxStreamID, MaxRoadID; clock_t start, finish1; double runtime = 0.0; int t = 0; float roadarea; int i; int j; int x; /* row counter */ int y; /* column counter */ int shade_offset; /* a fast way of handling arraay position given the number of mm5 input options */ int NStats; /* Number of meteorological stations */ uchar ***MetWeights = NULL; /* 3D array with weights for interpolating meteorological variables between the stations */ int NGraphics; /* number of graphics for X11 */ int *which_graphics; /* which graphics for X11 */ AGGREGATED Total = { /* Total or average value of a variable over the entire basin */ {0.0, NULL, NULL, NULL, NULL, 0.0}, /* EVAPPIX */ {0.0, 0.0, 0.0, 0.0, 0.0, NULL, NULL, 0.0, 0, 0.0}, /* PRECIPPIX */ {{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, 0.0, {0.0, 0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, /* PIXRAD */ {0.0, 0.0, 0, NULL, NULL, 0.0, 0, 0.0, 0.0, 0.0, 0.0, NULL, NULL}, /* ROADSTRUCT*/ {0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, /* SNOWPIX */ {0, 0.0, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, /* SOILPIX */ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0l, 0.0, 0.0 }; CHANNEL ChannelData = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; DUMPSTRUCT Dump; EVAPPIX **EvapMap = NULL; INPUTFILES InFiles; LAYER Soil; LAYER Veg; LISTPTR Input = NULL; /* Linked list with input strings */ MAPSIZE Map; /* Size and location of model area */ MAPSIZE Radar; /* Size and location of area covered by precipitation radar */ MAPSIZE MM5Map; /* Size and location of area covered by MM5 input files */ GRID Grid; METLOCATION *Stat = NULL; OPTIONSTRUCT Options; /* Structure with information which program options to follow */ PIXMET LocalMet; /* Meteorological conditions for current pixel */ PRECIPPIX **PrecipMap = NULL; RADARPIX **RadarMap = NULL; PIXRAD **RadiationMap = NULL; ROADSTRUCT **Network = NULL; /* 2D Array with channel information for each pixel */ SNOWPIX **SnowMap = NULL; GLPIX **GlacierMap = NULL; /* glacier model*/ MET_MAP_PIX **MetMap = NULL; SNOWTABLE *SnowAlbedo = NULL; SOILPIX **SoilMap = NULL; SOILTABLE *SType = NULL; SOLARGEOMETRY SolarGeo; /* Geometry of Sun-Earth system (needed for INLINE radiation calculations */ TIMESTRUCT Time; TOPOPIX **TopoMap = NULL; UNITHYDR **UnitHydrograph = NULL; UNITHYDRINFO HydrographInfo; /* Information about unit hydrograph */ VEGPIX **VegMap = NULL; VEGTABLE *VType = NULL; WATERBALANCE Mass = /* parameter for mass balance calculations */ { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /***************************************************************************** Initialization Procedures *****************************************************************************/ if (argc != 2) { fprintf(stderr, "\nUsage: %s inputfile\n\n", argv[0]); fprintf(stderr, "DHSVM uses two output streams: \n"); fprintf(stderr, "Standard Out, for the majority of output \n"); fprintf(stderr, "Standard Error, for the final mass balance \n"); fprintf(stderr, "\nTo pipe output correctly to files: \n"); fprintf(stderr, "(cmd > f1) >& f2 \n"); fprintf(stderr, "where f1 is stdout_file and f2 is stderror_file\n"); exit(EXIT_FAILURE); } sprintf(commandline, "%s %s", argv[0], argv[1]); printf("%s \n", commandline); fprintf(stderr, "%s \n", commandline); strcpy(InFiles.Const, argv[1]); printf("\nRunning DHSVM %s\n", version); printf("\nSTARTING INITIALIZATION PROCEDURES\n\n"); /* Start recording time */ start = clock(); ReadInitFile(InFiles.Const, &Input); InitConstants(Input, &Options, &Map, &SolarGeo, &Time); InitFileIO(Options.FileFormat); InitTables(Time.NDaySteps, Input, &Options, &SType, &Soil, &VType, &Veg, &SnowAlbedo); InitGlacierMap(&Map, &GlacierMap); /*glacier model*/ InitTerrainMaps(Input, &Options, &Map, &Soil, &TopoMap, &SoilMap, &VegMap, &GlacierMap); CheckOut(&Options, Veg, Soil, VType, SType, &Map, TopoMap, VegMap, SoilMap); if (Options.HasNetwork) InitChannel(Input, &Map, Time.Dt, &ChannelData, SoilMap, &MaxStreamID, &MaxRoadID, &Options); else if (Options.Extent != POINT) InitUnitHydrograph(Input, &Map, TopoMap, &UnitHydrograph, &Hydrograph, &HydrographInfo); InitNetwork(Map.NY, Map.NX, Map.DX, Map.DY, TopoMap, SoilMap, VegMap, VType, &Network, &ChannelData, Veg, &Options); InitMetSources(Input, &Options, &Map, TopoMap, Soil.MaxLayers, &Time, &InFiles, &NStats, &Stat, &Radar, &MM5Map, &Grid); /* the following piece of code is for the UW PRISM project */ /* for real-time verification of SWE at Snotel sites */ /* Other users, set OPTION.SNOTEL to FALSE, or use TRUE with caution */ if (Options.Snotel == TRUE && Options.Outside == FALSE) { printf ("Warning: All met stations locations are being set to the vegetation class GLACIER\n"); printf ("Warning: This requires that you have such a vegetation class in your vegetation table\n"); printf("To disable this feature set Snotel OPTION to FALSE\n"); for (i = 0; i < NStats; i++) { printf("veg type for station %d is %d ", i, VegMap[Stat[i].Loc.N][Stat[i].Loc.E].Veg); for (j = 0; j < Veg.NTypes; j++) { if (VType[j].Index == GLACIER) { VegMap[Stat[i].Loc.N][Stat[i].Loc.E].Veg = j; break; } } if (j == Veg.NTypes) { /* glacier class not found */ ReportError("MainDHSVM", 62); } printf("setting to glacier type (assumed bare class): %d\n", j); } } InitMetMaps(Time.NDaySteps, &Map, &Radar, &Options, InFiles.WindMapPath, InFiles.PrecipLapseFile, &PrecipLapseMap, &PrismMap, &ShadowMap, &SkyViewMap, &EvapMap, &PrecipMap, &RadarMap, &RadiationMap, SoilMap, &Soil, VegMap, &Veg, TopoMap, &MM5Input, &WindModel); InitInterpolationWeights(&Map, &Options, TopoMap, &MetWeights, Stat, NStats); InitDump(Input, &Options, &Map, Soil.MaxLayers, Veg.MaxLayers, Time.Dt, TopoMap, &Dump, &NGraphics, &which_graphics); if (Options.HasNetwork == TRUE) { InitChannelDump(&Options, &ChannelData, Dump.Path); ReadChannelState(Dump.InitStatePath, &(Time.Start), ChannelData.streams); if (Options.StreamTemp && Options.CanopyShading) InitChannelRVeg(&Time, ChannelData.streams); } InitSnowMap(&Map, &SnowMap); InitAggregated(Veg.MaxLayers, Soil.MaxLayers, &Total); InitModelState(&(Time.Start), &Map, &Options, PrecipMap, SnowMap, SoilMap, Soil, SType, VegMap, Veg, VType, Dump.InitStatePath, SnowAlbedo, TopoMap, Network, &HydrographInfo, Hydrograph, &Total, GlacierMap); #ifdef HAVE_GLACIER /* Glacier Model is run independently to "spinup" glacier ice state over 1000 years */ if (Options.Glacier == GLSPINUP){ dt_year = 1; year_min = 0; year_max = 1000; printf("Glacier model spin up run for %f years\n", year_max); main_spinup(&Map, TopoMap, SnowMap,GlacierMap, dt_year,year_min,year_max, &(Time.Current), &Dump, &Options); return EXIT_SUCCESS; } #endif InitNewMonth(&Time, &Options, &Map, TopoMap, PrismMap, ShadowMap, &InFiles, Veg.NTypes, VType, NStats, Stat, Dump.InitStatePath); InitNewDay(Time.Current.JDay, &SolarGeo); if (NGraphics > 0) { printf("Initialzing X11 display and graphics \n"); InitXGraphics(argc, argv, Map.NY, Map.NX, NGraphics, &MetMap); } shade_offset = FALSE; if (Options.Shading == TRUE) shade_offset = TRUE; /* Done with initialization, delete the list with input strings */ DeleteList(Input); /* setup for mass balance calculations */ Aggregate(&Map, &Options, TopoMap, &Soil, &Veg, VegMap, EvapMap, PrecipMap, RadiationMap, SnowMap, SoilMap, &Total, VType, Network, &ChannelData, &roadarea); Mass.StartWaterStorage = Total.Soil.IExcess + Total.CanopyWater + Total.SoilWater + Total.Snow.Swq + Total.Soil.SatFlow + Total.Snow.Iwq + Total.Snow.IceRemoved; Mass.OldWaterStorage = Mass.StartWaterStorage; /* computes the number of grid cell contributing to one segment */ if (Options.StreamTemp) Init_segment_ncell(TopoMap, ChannelData.stream_map, Map.NY, Map.NX, ChannelData.streams); /***************************************************************************** Perform Calculations *****************************************************************************/ while (Before(&(Time.Current), &(Time.End)) || IsEqualTime(&(Time.Current), &(Time.End))) { /* debug */ if (Time.Current.Month == 5 && Time.Current.Day == 20 && Time.Current.Hour >= 9 && Time.Current.Hour <= 15) printf("stop here for a little\n"); /* debug ends */ /* reset aggregated variables */ ResetAggregate(&Soil, &Veg, &Total, &Options); if (IsNewMonth(&(Time.Current), Time.Dt)){ InitNewMonth(&Time, &Options, &Map, TopoMap, PrismMap, ShadowMap, &InFiles, Veg.NTypes, VType, NStats, Stat, Dump.InitStatePath); #ifdef HAVE_GLACIER /* Run the glacier model at the end of every month */ if (Options.Glacier == GLSTATIC || Options.Glacier == GLDYNAMIC){ dt_year = 1.0; year_min = 1.0; year_max = 1.0; if(Time.Current.Month == 10 && Time.Current.Day == 1){ /* Calculate Equilibrium Line Altitude at end of Water Year (assumed Oct1) */ /* will need to be changed depending on geography define water year */ calc_ela(&Map, TopoMap,SnowMap,GlacierMap,&(Time.Current), &Dump); } main_gl(&Map, TopoMap, SnowMap,GlacierMap, dt_year,year_min,year_max, &(Time.Current), &Dump,&Options); /*Use the next program to output balance information for indivdual glaciers */ gl_massbalance(&Map, TopoMap, SnowMap,GlacierMap, dt_year,year_min, year_max, &(Time.Current), &Dump); } #endif } if (IsNewDay(Time.DayStep)) { InitNewDay(Time.Current.JDay, &SolarGeo); PrintDate(&(Time.Current), stdout); printf("\n"); } InitNewStep(&InFiles, &Map, &Time, Soil.MaxLayers, &Options, NStats, Stat, InFiles.RadarFile, &Radar, RadarMap, &SolarGeo, TopoMap, SoilMap, MM5Input, WindModel, &MM5Map); /* initialize channel/road networks for time step */ if (Options.HasNetwork) { channel_step_initialize_network(ChannelData.streams); channel_step_initialize_network(ChannelData.roads); } for (y = 0; y < Map.NY; y++) { for (x = 0; x < Map.NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { if (Options.Shading) LocalMet = MakeLocalMetData(y, x, &Map, Time.DayStep, &Options, NStats, Stat, MetWeights[y][x], TopoMap[y][x].Dem, &(RadiationMap[y][x]), &(PrecipMap[y][x]), &Radar, RadarMap, PrismMap, &(SnowMap[y][x]), SnowAlbedo, MM5Input, WindModel, PrecipLapseMap, &MetMap, NGraphics, Time.Current.Month, SkyViewMap[y][x], ShadowMap[Time.DayStep][y][x], SolarGeo.SunMax, SolarGeo.SineSolarAltitude); else LocalMet = MakeLocalMetData(y, x, &Map, Time.DayStep, &Options, NStats, Stat, MetWeights[y][x], TopoMap[y][x].Dem, &(RadiationMap[y][x]), &(PrecipMap[y][x]), &Radar, RadarMap, PrismMap, &(SnowMap[y][x]), SnowAlbedo, MM5Input, WindModel, PrecipLapseMap, &MetMap, NGraphics, Time.Current.Month, 0.0, 0.0, SolarGeo.SunMax, SolarGeo.SineSolarAltitude); /* get surface tempeature of each soil layer */ for (i = 0; i < Soil.MaxLayers; i++) { if (Options.HeatFlux == TRUE) { if (Options.MM5 == TRUE) SoilMap[y][x].Temp[i] = MM5Input[shade_offset + i + N_MM5_MAPS][y][x]; /* read tempeature of each soil layer from met station input */ else SoilMap[y][x].Temp[i] = Stat[0].Data.Tsoil[i]; } /* if heat flux option is turned off, soil temperature of all 3 layers is taken equal to air tempeature */ else SoilMap[y][x].Temp[i] = LocalMet.Tair; } MassEnergyBalance(&Options, y, x, SolarGeo.SineSolarAltitude, Map.DX, Map.DY, Time.Dt, Options.HeatFlux, Options.CanopyRadAtt, Options.Infiltration, Veg.MaxLayers, &LocalMet, &(Network[y][x]), &(PrecipMap[y][x]), &(VType[VegMap[y][x].Veg-1]), &(VegMap[y][x]), &(SType[SoilMap[y][x].Soil-1]), &(SoilMap[y][x]), &(SnowMap[y][x]), &(RadiationMap[y][x]), &(EvapMap[y][x]), &(Total.Rad), &ChannelData, SkyViewMap); PrecipMap[y][x].SumPrecip += PrecipMap[y][x].Precip; } } } /* Average all RBM inputs over each segment */ if (Options.StreamTemp) { channel_grid_avg(ChannelData.streams); if (Options.CanopyShading) CalcCanopyShading(&Time, ChannelData.streams, &SolarGeo); } #ifndef SNOW_ONLY RouteSubSurface(Time.Dt, &Map, TopoMap, VType, VegMap, Network, SType, SoilMap, &ChannelData, &Time, &Options, Dump.Path, MaxStreamID, SnowMap); if (Options.HasNetwork) RouteChannel(&ChannelData, &Time, &Map, TopoMap, SoilMap, &Total, &Options, Network, SType, PrecipMap, LocalMet.Tair, LocalMet.Rh); if (Options.Extent == BASIN) RouteSurface(&Map, &Time, TopoMap, SoilMap, &Options, UnitHydrograph, &HydrographInfo, Hydrograph, &Dump, VegMap, VType, &ChannelData); #endif if (NGraphics > 0) draw(&(Time.Current), IsEqualTime(&(Time.Current), &(Time.Start)), Time.DayStep, &Map, NGraphics, which_graphics, VType, SType, SnowMap, SoilMap, VegMap, TopoMap, PrecipMap, PrismMap, SkyViewMap, ShadowMap, EvapMap, RadiationMap, MetMap, Network, &Options); Aggregate(&Map, &Options, TopoMap, &Soil, &Veg, VegMap, EvapMap, PrecipMap, RadiationMap, SnowMap, SoilMap, &Total, VType, Network, &ChannelData, &roadarea); MassBalance(&(Time.Current), &(Time.Start), &(Dump.Balance), &Total, &Mass); ExecDump(&Map, &(Time.Current), &(Time.Start), &Options, &Dump, TopoMap, EvapMap, RadiationMap, PrecipMap, SnowMap, MetMap, VegMap, &Veg, SoilMap, Network, &ChannelData, &Soil, &Total, &HydrographInfo,Hydrograph); IncreaseTime(&Time); t += 1; } ExecDump(&Map, &(Time.Current), &(Time.Start), &Options, &Dump, TopoMap, EvapMap, RadiationMap, PrecipMap, SnowMap, MetMap, VegMap, &Veg, SoilMap, Network, &ChannelData, &Soil, &Total, &HydrographInfo, Hydrograph); FinalMassBalance(&(Dump.FinalBalance), &Total, &Mass); printf("\nEND OF MODEL RUN\n\n"); /* record the run time at the end of each time loop */ finish1 = clock (); runtime = (finish1-start)/CLOCKS_PER_SEC; printf("***********************************************************************************"); printf("\nRuntime Summary:\n"); printf("%6.2f hours elapsed for the simulation period of %d hours (%.1f days) \n", runtime/3600, t*Time.Dt/3600, (float)t*Time.Dt/3600/24); return EXIT_SUCCESS; }