int main(void) { MAPDUMP DMap; int i = 0; DMap.Layer = 2; while (varinfo[i].ID != ENDOFLIST) { strcpy(DMap.FileName, "<path>/"); DMap.Resolution = i % 2; if (DMap.Resolution == 0) DMap.Resolution += 2; DMap.ID = varinfo[i].ID; if (IsValidID(DMap.ID)) { /* only added to test IsvalidID */ GetVarAttr(&DMap); printf("************************************************************\n"); printf("ID : %d\n", DMap.ID); printf("Name : %s\n", DMap.Name); printf("LongName : %s\n", DMap.LongName); printf("FileName : %s\n", DMap.FileName); printf("FileLabel : %s\n", DMap.FileLabel); printf("Format : %s\n", DMap.Format); printf("Units : %s\n", DMap.Units); printf("NumberType: %d\n", DMap.NumberType); printf("NLayers : %d\n", GetVarNLayers(DMap.ID, 2, 3)); printf("FileName : %s\n", DMap.FileName); printf("************************************************************\n"); i++; } } DMap.ID = -1; if (IsValidID(DMap.ID)) { /* only added to test IsvalidID */ GetVarAttr(&DMap); } else return EXIT_SUCCESS; printf("Error: the test program should not have reached this line\n"); return EXIT_FAILURE; }
/***************************************************************************** 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. *****************************************************************************/ void InitModelState(DATE * Start, MAPSIZE * Map, OPTIONSTRUCT * Options, PRECIPPIX ** PrecipMap, SNOWPIX ** SnowMap, SOILPIX ** SoilMap, LAYER Soil, SOILTABLE * SType, VEGCHEMPIX ** VegChemMap, LAYER Veg, VEGTABLE * VType, char *Path, SNOWTABLE * SnowAlbedo, TOPOPIX ** TopoMap, ROADSTRUCT ** Network, UNITHYDRINFO * HydrographInfo, float *Hydrograph) { const char *Routine = "InitModelState"; char Str[NAMESIZE + 1]; char FileName[NAMESIZE + 1]; FILE *HydroStateFile; int i; /* counter */ int x; /* counter */ int y; /* counter */ int NSet; /* Number of dataset to be read */ int NSoil; /* Number of soil layers for current pixel */ int NVeg; /* Number of veg layers for current pixel */ void *Array; MAPDUMP DMap; /* Dump Info */ float remove; /* Restore canopy interception */ NSet = 0; if (DEBUG) printf("Restoring canopy conditions\n"); sprintf(Str, "%02d.%02d.%02d.%02d.%02d.%02d", Start->Month, Start->Day, Start->Year, Start->Hour, Start->Min, Start->Sec); printf("Reading %sInterception.State.%s%s...\n",Path, Str, fileext); sprintf(FileName, "%sInterception.State.%s%s", Path, Str, fileext); DMap.ID = 202; DMap.Layer = 0; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); if (!(Array = calloc(Map->NY * Map->NX, SizeOfNumberType(DMap.NumberType)))) ReportError((char *) Routine, 1); for (i = 0; i < Veg.MaxLayers; i++) { DMap.ID = 202; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { PrecipMap[y][x].IntRain[i] = 0.0; NVeg = Veg.NLayers[(VegChemMap[y][x].Veg - 1)]; if (i < NVeg) { PrecipMap[y][x].IntRain[i] = ((float *) Array)[y * Map->NX + x]; if (PrecipMap[y][x].IntRain[i] < 0.0) { fprintf(stderr, "InitModelState at (x, y) is (%d, %d):\n", x, y); fprintf(stderr, "\tRain interception negative on layer %d of max %d ... reset to 0\n", i, Veg.MaxLayers); PrecipMap[y][x].IntRain[i] = 0.0; } } } } } } for (i = 0; i < Veg.MaxLayers; i++) { DMap.ID = 203; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++,DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { PrecipMap[y][x].IntSnow[i] = 0.0; NVeg = Veg.NLayers[(VegChemMap[y][x].Veg - 1)]; if (i < NVeg) { PrecipMap[y][x].IntSnow[i] = ((float *) Array)[y * Map->NX + x]; if (PrecipMap[y][x].IntSnow[i] < 0.0) { fprintf(stderr, "InitModelState at (x, y) is (%d, %d):\n", x, y); fprintf(stderr,"Snow interception negative on layer %d of max %d ... reset to 0\n",i, Veg.MaxLayers); PrecipMap[y][x].IntSnow[i] = 0.0; } } } } } } DMap.ID = 204; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++,DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { PrecipMap[y][x].TempIntStorage = ((float *) Array)[y * Map->NX + x]; if (PrecipMap[y][x].TempIntStorage < 0.0) { fprintf(stderr, "InitModelState at (x, y) is (%d, %d):\n", x, y); fprintf(stderr, "Total intercepted precipitation negative on layer %d of max %d ... reset to 0\n", i, Veg.MaxLayers); PrecipMap[y][x].TempIntStorage = 0.0; } } } } free(Array); /* Restore snow pack conditions */ NSet = 0; if (DEBUG) printf("Restoring snow pack conditions\n"); printf("Reading %sSnow.State.%s%s...\n",Path, Str, fileext); sprintf(FileName, "%sSnow.State.%s%s", Path, Str, fileext); DMap.ID = 401; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); if (!(Array = (float *) calloc(Map->NY * Map->NX, SizeOfNumberType(DMap.NumberType)))) ReportError((char *) Routine, 1); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].HasSnow = (unsigned char) ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 403; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].LastSnow = (unsigned short) ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 404; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].Swq = ((float *) Array)[y * Map->NX + x]; //if ( SnowMap[y][x].Swq > 100 ) SnowMap[y][x].Swq = 100; } } } DMap.ID = 406; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].PackWater = ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 407; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].TPack = ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 408; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].SurfWater = ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 409; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].TSurf = ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 410; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SnowMap[y][x].ColdContent = ((float *) Array)[y * Map->NX + x]; } } } free(Array); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { if (SnowMap[y][x].HasSnow) { SnowMap[y][x].Albedo = CalcSnowAlbedo(SnowMap[y][x].TSurf, SnowMap[y][x].LastSnow, SnowAlbedo); } else { SnowMap[y][x].Albedo = 0; } SnowMap[y][x].ShearStress = 0.0; SnowMap[y][x].IceA = 0.0; SnowMap[y][x].IceFlux = 0.0; SnowMap[y][x].IceVelocity = 0.0; } else { SnowMap[y][x].ShearStress = NA; SnowMap[y][x].IceA = NA; SnowMap[y][x].IceFlux = NA; SnowMap[y][x].Albedo = NA; SnowMap[y][x].IceVelocity = NA; } } } /* Restore soil conditions */ NSet = 0; printf("Reading %sSoil.State.%s%s...\n",Path, Str, fileext); sprintf(FileName, "%sSoil.State.%s%s", Path, Str, fileext); DMap.ID = 501; DMap.Layer = 0; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); if (!(Array = (float *) calloc(Map->NY * Map->NX, SizeOfNumberType(DMap.NumberType)))) ReportError((char *) Routine, 1); for (i = 0; i < Soil.MaxLayers + 1; i++) { DMap.ID = 501; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++,DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { NSoil = Soil.NLayers[(SoilMap[y][x].Soil - 1)]; if (i <= NSoil) { SoilMap[y][x].Moist_m_m[i] = ((float *) Array)[y * Map->NX + x]; if (SoilMap[y][x].Moist_m_m[i] < 0.0) { fprintf(stderr, "InitModelState at (x, y) is (%d, %d):\n", x, y); fprintf(stderr,"Soil moisture negative in layer %d of max %d ... reset to 0, was %f\n", i, Soil.MaxLayers, SoilMap[y][x].Moist_m_m[i]); SoilMap[y][x].Moist_m_m[i] = 0.0; } } /* this appears to be redundant - value also set by init-state file jsb 3/4/09 if (i == NSoil) { if (SoilMap[y][x].Moist_m_m[i] < SType[SoilMap[y][x].Soil - 1].FCap[NSoil - 1]) SoilMap[y][x].Moist_m_m[i] = SType[SoilMap[y][x].Soil - 1].FCap[NSoil - 1]; } if (i < NSoil) { if (SoilMap[y][x].Moist_m_m[i] <SType[SoilMap[y][x].Soil - 1].WP[NSoil - 1]) { SoilMap[y][x].Moist_m_m[i] = SType[SoilMap[y][x].Soil - 1].WP[NSoil - 1]; } }*/ } } } } DMap.ID = 505; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SoilMap[y][x].TSurf = ((float *) Array)[y * Map->NX + x]; } } } for (i = 0; i < Soil.MaxLayers; i++) { DMap.ID = 511; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); printf("Reading Soil Temperature State[%d]\n",i); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { NSoil = Soil.NLayers[(SoilMap[y][x].Soil - 1)]; if (i < NSoil) SoilMap[y][x].Temp[i] = ((float *) Array)[y * Map->NX + x]; } } } } DMap.ID = 510; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SoilMap[y][x].Qst = ((float *) Array)[y * Map->NX + x]; } } } DMap.ID = 512; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Read2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, NSet++, DMap.Name); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SoilMap[y][x].Runoff_m = ((float *) Array)[y * Map->NX + x]; //DISABLEDTEST: BURPTEST((SoilMap[y][x].Runoff_m<1),"( SoilMap[y][x].Runoff_m <1)"); } } } free(Array); /* Calculate the water table depth at each point based on the soil moisture profile. Give an error message if the water ponds on the surface since that should not be allowed at this point */ remove = 0.0; for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { /* SatFlow_m needs to be initialized properly in the future. For now it will just be set to zero here */ SoilMap[y][x].SatFlow_m = 0.0; if (INBASIN(TopoMap[y][x].Mask)) { if ((SoilMap[y][x].TableDepth_m = WaterTableDepth((Soil.NLayers[SoilMap[y][x].Soil - 1]),SoilMap[y][x].Depth,VType[VegChemMap[y][x].Veg - 1].RootDepth_m, SType[SoilMap[y][x].Soil - 1].Porosity, SType[SoilMap[y][x].Soil - 1].FCap,Network[y][x].Adjust, SoilMap[y][x].Moist_m_m))< 0.0){ remove -= SoilMap[y][x].TableDepth_m * Map->DX * Map->DY; SoilMap[y][x].TableDepth_m = 0.0; } } else SoilMap[y][x].TableDepth_m = 0; } } if (remove > 0.0) { printf("WARNING:excess water in soil profile is %f m^3 \n", remove); printf("Expect possible large flood wave during first timesteps \n"); } /* If the unit hydrograph is used for flow routing, initialize the unit hydrograph array */ if (Options->Extent == BASIN && Options->HasNetwork == FALSE) { sprintf(FileName, "%sHydrograph.State.%s", Path, Str); OpenFile(&HydroStateFile, FileName, "r", FALSE); for (i = 0; i < HydrographInfo->TotalWaveLength; i++) fscanf(HydroStateFile, "%f\n", &(Hydrograph[i])); fclose(HydroStateFile); } }
/******************************************************************************* 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); } }
/******************************************************************************* 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 : *******************************************************************************/ void InitMapDump(LISTPTR Input, MAPSIZE * Map, int MaxSoilLayers, int MaxVegLayers, char *Path, int TotalMapImages, int NMaps, MAPDUMP ** DMap) { char *Routine = "InitMapDump"; int i; /* counter */ int j; /* counter */ int MaxLayers; /* Maximum number of layers allowed for this variable */ char KeyName[map_date + 1][BUFSIZE + 1]; char *KeyStr[] = { "MAP VARIABLE", "MAP LAYER", "NUMBER OF MAPS", "MAP DATE", }; char *SectionName = "OUTPUT"; char VarStr[map_date + 1][BUFSIZE + 1]; if (!(*DMap = (MAPDUMP *)calloc(TotalMapImages, sizeof(MAPDUMP)))) ReportError(Routine, 1); for (i = 0; i < NMaps; i++) { /* Read the key-entry pairs from the input file */ for (j = 0; j <= nmaps; j++) { sprintf(KeyName[j], "%s %d", KeyStr[j], i + 1); GetInitString(SectionName, KeyName[j], "", VarStr[j], (unsigned long)BUFSIZE, Input); } /* Assign the entries to the appropriate variables */ if (!CopyInt(&((*DMap)[i].ID), VarStr[map_variable], 1)) ReportError(KeyName[map_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[map_layer], 1)) ReportError(KeyName[map_layer], 51); if ((*DMap)[i].Layer < 1 || (*DMap)[i].Layer > MaxLayers) ReportError("Input Options File", 20); } else (*DMap)[i].Layer = 1; (*DMap)[i].Resolution = MAP_OUTPUT; strncpy((*DMap)[i].FileName, Path, BUFSIZE); GetVarAttr(&((*DMap)[i])); CreateMapFile((*DMap)[i].FileName, (*DMap)[i].FileLabel, Map); if (!CopyInt(&((*DMap)[i].N), VarStr[nmaps], 1)) ReportError(KeyName[nmaps], 51); if ((*DMap)[i].N < 1) ReportError("Input Options File", 22); if (!((*DMap)[i].DumpDate = (DATE *)calloc((*DMap)[i].N, sizeof(DATE)))) ReportError(Routine, 1); for (j = 0; j < (*DMap)[i].N; j++) { sprintf(KeyName[map_date], "%s %d %d", KeyStr[map_date], j + 1, i + 1); GetInitString(SectionName, KeyName[map_date], "", VarStr[map_date], (unsigned long)BUFSIZE, Input); if (!SScanDate(VarStr[map_date], &((*DMap)[i].DumpDate[j]))) ReportError(KeyName[map_date], 51); } (*DMap)[i].MinVal = 0.0; (*DMap)[i].MaxVal = 0.0; } }
/***************************************************************************** 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 *****************************************************************************/ void StoreModelState(char *Path, DATE * Current, MAPSIZE * Map, OPTIONSTRUCT * Options, TOPOPIX ** TopoMap, PRECIPPIX ** PrecipMap, SNOWPIX ** SnowMap, MET_MAP_PIX ** MetMap, RADCLASSPIX ** RadMap, VEGCHEMPIX ** VegChemMap, LAYER * Veg, SOILPIX ** SoilMap, LAYER * Soil, UNITHYDRINFO * HydrographInfo, float *Hydrograph) { const char *Routine = "StoreModelState"; char Str[NAMESIZE + 1]; char FileLabel[MAXSTRING + 1]; char FileName[NAMESIZE + 1]; FILE *HydroStateFile; int i; /* counter */ int x; /* counter */ int y; /* counter */ int NSoil; /* Number of soil layers for current pixel */ int NVeg; /* Number of veg layers for current pixel */ MAPDUMP DMap; /* Dump Info */ void *Array; /* print a message to stdout that state is being stored */ printf("Saving Model State at: "); PrintDate(Current, stdout); printf("\n"); /* Only save met state during debug, it is not needed for start-up */ if (MetMap != NULL && DEBUG) { sprintf(Str, "%02d.%02d.%04d.%02d.%02d.%02d", Current->Month, Current->Day, Current->Year, Current->Hour, Current->Min, Current->Sec); sprintf(FileName, "%sMet.State.%s%s", Path, Str, fileext); strcpy(FileLabel, "Basic Meteorology at time step"); CreateMapFile(FileName, FileLabel, Map); if (!(Array = (float *) calloc(Map->NY * Map->NX, sizeof(float)))) ReportError((char *) Routine, 1); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = PrecipMap[y][x].Precip; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 201; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = MetMap[y][x].accum_precip; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 701; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = MetMap[y][x].air_temp; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 702; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = MetMap[y][x].wind_speed; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 703; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = MetMap[y][x].humidity; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 704; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = RadMap[y][x].Beam + RadMap[y][x].Diffuse; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 303; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); free(Array); } /* Store the canopy interception */ sprintf(Str, "%02d.%02d.%04d.%02d.%02d.%02d", Current->Month, Current->Day, Current->Year, Current->Hour, Current->Min, Current->Sec); printf("Writing %sInterception.State.%s%s...\n", Path, Str, fileext); sprintf(FileName, "%sInterception.State.%s%s", Path, Str, fileext); strcpy(FileLabel, "Interception storage for each vegetation layer"); CreateMapFile(FileName, FileLabel, Map); if (!(Array = (float *) calloc(Map->NY * Map->NX, sizeof(float)))) ReportError((char *) Routine, 1); for (i = 0; i < Veg->MaxLayers; i++) { for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { NVeg = Veg->NLayers[(VegChemMap[y][x].Veg - 1)]; if (i < NVeg) ((float *) Array)[y * Map->NX + x] = PrecipMap[y][x].IntRain[i]; else ((float *) Array)[y * Map->NX + x] = NA; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 202; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); } for (i = 0; i < Veg->MaxLayers; i++) { for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { NVeg = Veg->NLayers[(VegChemMap[y][x].Veg - 1)]; if (i < NVeg) ((float *) Array)[y * Map->NX + x] = PrecipMap[y][x].IntSnow[i]; else ((float *) Array)[y * Map->NX + x] = NA; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 203; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); } for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { ((float *) Array)[y * Map->NX + x] = PrecipMap[y][x].TempIntStorage; } else { ((float *) Array)[y * Map->NX + x] = NA; } } } DMap.ID = 204; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); free(Array); /* Store the snow pack conditions */ printf("Writing %sSnow.State.%s%s...\n", Path, Str, fileext); sprintf(FileName, "%sSnow.State.%s%s", Path, Str, fileext); strcpy(FileLabel, "Snow pack moisture and temperature state"); CreateMapFile(FileName, FileLabel, Map); if (!(Array = (float *) calloc(Map->NY * Map->NX, sizeof(float)))) ReportError((char *) Routine, 1); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = (float) SnowMap[y][x].HasSnow; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 401; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = (float) SnowMap[y][x].LastSnow; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 403; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SnowMap[y][x].Swq; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 404; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SnowMap[y][x].PackWater; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 406; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SnowMap[y][x].TPack; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 407; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SnowMap[y][x].SurfWater; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 408; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SnowMap[y][x].TSurf; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 409; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SnowMap[y][x].ColdContent; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 410; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); free(Array); /* Store the soil conditions */ printf("Writing %sSoil.State.%s%s...\n", Path, Str, fileext); sprintf(FileName, "%sSoil.State.%s%s", Path, Str, fileext); strcpy(FileLabel, "Soil moisture and temperature state"); CreateMapFile(FileName, FileLabel, Map); if (!(Array = (float *) calloc(Map->NY * Map->NX, sizeof(float)))) ReportError((char *) Routine, 1); for (i = 0; i < Soil->MaxLayers + 1; i++) { for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { NSoil = Soil->NLayers[(SoilMap[y][x].Soil - 1)]; if (i <= NSoil) ((float *) Array)[y * Map->NX + x] = SoilMap[y][x].Moist_m_m[i]; else ((float *) Array)[y * Map->NX + x] = NA; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 501; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); } for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SoilMap[y][x].TSurf; else ((float *) Array)[y * Map->NX + x] = SoilMap[y][x].TSurf; } } DMap.ID = 505; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (i = 0; i < Soil->MaxLayers; i++) { for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { NSoil = Soil->NLayers[SoilMap[y][x].Soil - 1]; if (i < NSoil) ((float *) Array)[y * Map->NX + x] = SoilMap[y][x].Temp[i]; else ((float *) Array)[y * Map->NX + x] = NA; } else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 511; DMap.Layer = i; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); } for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SoilMap[y][x].Qst; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 510; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) ((float *) Array)[y * Map->NX + x] = SoilMap[y][x].Runoff_m; else ((float *) Array)[y * Map->NX + x] = NA; } } DMap.ID = 512; DMap.Resolution = MAP_OUTPUT; strcpy(DMap.FileName, ""); GetVarAttr(&DMap); Write2DMatrix(FileName, Array, DMap.NumberType, Map->NY, Map->NX, &DMap, 0); free(Array); /* If the unit hydrograph is used for flow routing, store the unit hydrograph array */ if (Options->Extent == BASIN && Options->HasNetwork == FALSE) { sprintf(FileName, "%sHydrograph.State.%s", Path, Str); OpenFile(&HydroStateFile, FileName, "w", FALSE); for (i = 0; i < HydrographInfo->TotalWaveLength; i++) fprintf(HydroStateFile, "%f\n", Hydrograph[i]); fclose(HydroStateFile); } }