/******************************************************************************* 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 : *****************************************************************************/ void InitStations(LISTPTR Input, MAPSIZE *Map, int NDaySteps, OPTIONSTRUCT *Options, int *NStats, METLOCATION **Stat) { char *Routine = "InitStations"; int i; int j; int k; char tempfilename[BUFSIZE + 1]; char KeyName[station_file + 1][BUFSIZE + 1]; char *KeyStr[] = { "STATION NAME", "NORTH COORDINATE", "EAST COORDINATE", "ELEVATION", "STATION FILE" }; char *SectionName = "METEOROLOGY"; char VarStr[station_file + 1][BUFSIZE + 1]; float East; float North; FILE *PrismStatFile; /* Get the number of different stations */ GetInitString(SectionName, "NUMBER OF STATIONS", "", VarStr[0], (unsigned long)BUFSIZE, Input); if (!CopyInt(NStats, VarStr[0], 1)) ReportError("NUMBER OF STATIONS", 51); if (*NStats <= 0) ReportError("Input Options File", 6); printf("\nEvaluating %d Met stations for inclusion\n", *NStats); /* Allocate memory for the stations */ if (!(*Stat = (METLOCATION *)calloc(*NStats, sizeof(METLOCATION)))) ReportError(Routine, 1); /* Read key-entry pairs for each station from the input file */ /* for each potential station, up to NStats, read in the data and */ /* determine if it is in the current model bounding box */ /* If it is then put it into memory, otherwise, forget about it */ /* unless Outside option is TRUE, then include it anyway */ /* use temp counter k to track number of valid stations */ k = 0; for (i = 0; i < *NStats; i++) { for (j = 0; j <= station_file; 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 variables */ if (IsEmptyStr(VarStr[station_name])) ReportError(KeyName[number_of_maps], 51); strcpy((*Stat)[k].Name, VarStr[station_name]); if (!CopyFloat(&North, VarStr[station_north], 1)) ReportError(KeyName[station_north], 51); if (!CopyFloat(&East, VarStr[station_east], 1)) ReportError(KeyName[station_east], 51); (*Stat)[k].Loc.N = Round(((Map->Yorig - 0.5 * Map->DY) - North) / Map->DY); (*Stat)[k].Loc.E = Round((East - (Map->Xorig + 0.5 * Map->DX)) / Map->DX); if (!CopyFloat(&((*Stat)[k].Elev), VarStr[station_elev], 1)) ReportError(KeyName[station_elev], 51); if (IsEmptyStr(VarStr[station_file])) ReportError(KeyName[station_file], 51); strcpy((*Stat)[k].MetFile.FileName, VarStr[station_file]); OpenFile(&((*Stat)[k].MetFile.FilePtr), (*Stat)[k].MetFile.FileName, "r", FALSE); /* check to see if the stations are inside the bounding box */ if (((*Stat)[k].Loc.N >= Map->NY || (*Stat)[k].Loc.N < 0 || (*Stat)[k].Loc.E >= Map->NX || (*Stat)[k].Loc.E < 0) && Options->Outside == FALSE) printf("Station %d outside bounding box: %s ignored\n", i + 1, (*Stat)[k].Name); else k = k + 1; } if (Options->Outside == FALSE) printf("Final number of stations in bounding box is %d \n\n", k); else printf("Forced to include all %d stations \n", k); *NStats = k; if (Options->Outside == TRUE && Options->Prism == TRUE) { for (i = 0; i < *NStats; i++) { sprintf(tempfilename, "%s.prism", (*Stat)[i].MetFile.FileName); /* Options->PrismDataExt); */ OpenFile(&PrismStatFile, tempfilename, "rt", FALSE); for (k = 0; k < 12; k++) { fscanf(PrismStatFile, "%f ", &(*Stat)[i].PrismPrecip[k]); } fclose(PrismStatFile); } } }
void GameDataHolder::Impl::Flush() { if( !FileExist( "save" ) ){ CreateDirectory( "save" ); } UpdatePlayTime(); std::vector < char > data; data.reserve( 30000 ); std::ofstream fOut( m_SaveDataFileName, std::ios::binary | std::ios::out ); if( !fOut ){ return; } CopyInt( &data, m_GameFileData.m_PlayTime ); CopyInt( &data, m_GameFileData.m_Progress ); for( int i = 0; i < GAME_DIFFICULTY_TOTAL; ++i ){ // 通常プレイの統計情報の保存 CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_Play ); CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_AllClear ); CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_PlayTime ); CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_Progress ); for( int j = 0; j < STAGE_TOTAL; ++j ){ // 敵情報の保存 const StageStat& stage = m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_StageStat[ j ]; StageStat::EnemyStatMap::const_iterator it = stage.m_EnemyStat.begin(); // エントリ数の保存 CopyInt( &data, stage.m_EnemyStat.size() ); for( ; it != stage.m_EnemyStat.end(); ++it ){ // 敵の名前の長さ保存 CopyInt( &data, it->first.size() ); // 敵の名前の保存 CopyArray( &data, it->first.c_str(), it->first.size() ); // 情報の保存 CopyInt( &data, it->second.m_Destroy ); CopyInt( &data, it->second.m_Damaged ); CopyInt( &data, it->second.m_KO ); } } // ステージ選択プレイの統計情報の保存 CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_Play ); CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_Clear ); CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_PlayTime ); for( int j = 0; j < STAGE_TOTAL; ++j ){ // 敵情報の保存 const StageStat& stage = m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_StageStat[ j ]; StageStat::EnemyStatMap::const_iterator it = stage.m_EnemyStat.begin(); // エントリ数の保存 CopyInt( &data, stage.m_EnemyStat.size() ); for( ; it != stage.m_EnemyStat.end(); ++it ){ // 敵の名前の長さ保存 CopyInt( &data, it->first.size() ); // 敵の名前の保存 CopyArray( &data, it->first.c_str(), it->first.size() ); // 情報の保存 CopyInt( &data, it->second.m_Destroy ); CopyInt( &data, it->second.m_Damaged ); CopyInt( &data, it->second.m_KO ); } } // スコアの保存 for( int j = 0; j < MAX_SCORE_ENTRY; ++j ){ SaveDataRecord record = m_GameFileData.m_Difficulty[ i ].m_Record[ j ]; CopyArray( &data, record.m_Name, sizeof( record.m_Name ) ); CopyInt( &data, record.m_Date.m_Year ); data.push_back( record.m_Date.m_Month ); data.push_back( record.m_Date.m_Day ); data.push_back( record.m_Date.m_Hour ); data.push_back( record.m_Date.m_Min ); data.push_back( record.m_Date.m_Sec ); for( int k = 0; k < STAGE_TOTAL; ++k ){ SaveDataRecord::StageData stage = record.m_StageData[ k ]; CopyInt( &data, stage.m_Score ); CopyInt( &data, stage.m_Killed ); CopyInt( &data, stage.m_Crystal ); CopyInt( &data, stage.m_CrystalUsed ); CopyInt( &data, stage.m_Progress ); } CopyInt( &data, record.m_Score ); CopyInt( &data, record.m_Progress ); CopyInt( &data, record.m_Killed ); CopyInt( &data, record.m_Crystal ); CopyInt( &data, record.m_CrystalUsed ); } } // 圧縮 char* pBuf = new char [ data.size() * 2 ]; int compSize = 0; MAPIL::LZ lz( 200, 3 ); lz.Compress( &data[ 0 ], data.size(), &pBuf, data.size() * 2, &compSize ); // シーザ暗号化 MAPIL::Caesar caesar( 10 ); caesar.Encrypt( pBuf, compSize ); // XOR暗号化 MAPIL::XOR xor( 60 ); xor.Encrypt( pBuf, compSize ); fOut.write( pBuf, compSize ); fOut.close(); MAPIL::SafeDeleteArray( pBuf ); }
/******************************************************************************* 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 : *****************************************************************************/ void InitMM5(LISTPTR Input, int NSoilLayers, TIMESTRUCT * Time, INPUTFILES * InFiles, OPTIONSTRUCT * Options, MAPSIZE * MM5Map, MAPSIZE * Map) { DATE Start; char *Routine = "InitMM5"; char KeyName[BUFSIZE + 1]; char VarStr[BUFSIZE + 1]; int i; STRINIENTRY StrEnv[] = { {"METEOROLOGY", "MM5 START", "", ""}, {"METEOROLOGY", "MM5 TEMPERATURE FILE", "", ""}, {"METEOROLOGY", "MM5 HUMIDITY FILE", "", ""}, {"METEOROLOGY", "MM5 WIND SPEED FILE", "", ""}, {"METEOROLOGY", "MM5 SHORTWAVE FILE", "", ""}, {"METEOROLOGY", "MM5 LONGWAVE FILE", "", ""}, {"METEOROLOGY", "MM5 PRECIPITATION FILE", "", ""}, {"METEOROLOGY", "MM5 TERRAIN FILE", "", ""}, {"METEOROLOGY", "MM5 TEMP LAPSE FILE", "", ""}, {"METEOROLOGY", "MM5 ROWS", "", ""}, {"METEOROLOGY", "MM5 COLS", "", ""}, {"METEOROLOGY", "MM5 EXTREME NORTH", "", ""}, {"METEOROLOGY", "MM5 EXTREME WEST", "", ""}, {"METEOROLOGY", "MM5 DY", "", ""}, {NULL, NULL, "", NULL}, }; /* Read the key-entry pairs from the input file */ for (i = 0; StrEnv[i].SectionName; i++) GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default, StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input); /* Assign the entries to the variables */ if (!SScanDate(StrEnv[MM5_start].VarStr, &Start)) ReportError(StrEnv[MM5_start].KeyName, 51); InitTime(Time, NULL, NULL, NULL, &Start, Time->Dt); if (IsEmptyStr(StrEnv[MM5_temperature].VarStr)) ReportError(StrEnv[MM5_temperature].KeyName, 51); strcpy(InFiles->MM5Temp, StrEnv[MM5_temperature].VarStr); if (IsEmptyStr(StrEnv[MM5_terrain].VarStr)) ReportError(StrEnv[MM5_terrain].KeyName, 51); strcpy(InFiles->MM5Terrain, StrEnv[MM5_terrain].VarStr); if (IsEmptyStr(StrEnv[MM5_lapse].VarStr)) ReportError(StrEnv[MM5_lapse].KeyName, 51); strcpy(InFiles->MM5Lapse, StrEnv[MM5_lapse].VarStr); if (IsEmptyStr(StrEnv[MM5_humidity].VarStr)) ReportError(StrEnv[MM5_humidity].KeyName, 51); strcpy(InFiles->MM5Humidity, StrEnv[MM5_humidity].VarStr); if (IsEmptyStr(StrEnv[MM5_wind].VarStr)) ReportError(StrEnv[MM5_wind].KeyName, 51); strcpy(InFiles->MM5Wind, StrEnv[MM5_wind].VarStr); if (IsEmptyStr(StrEnv[MM5_shortwave].VarStr)) ReportError(StrEnv[MM5_shortwave].KeyName, 51); strcpy(InFiles->MM5ShortWave, StrEnv[MM5_shortwave].VarStr); if (IsEmptyStr(StrEnv[MM5_longwave].VarStr)) ReportError(StrEnv[MM5_longwave].KeyName, 51); strcpy(InFiles->MM5LongWave, StrEnv[MM5_longwave].VarStr); if (IsEmptyStr(StrEnv[MM5_precip].VarStr)) ReportError(StrEnv[MM5_precip].KeyName, 51); strcpy(InFiles->MM5Precipitation, StrEnv[MM5_precip].VarStr); if (Options->HeatFlux == TRUE) { if (!(InFiles->MM5SoilTemp = (char **) calloc(sizeof(char *), NSoilLayers))) ReportError(Routine, 1); for (i = 0; i < NSoilLayers; i++) { if (! (InFiles->MM5SoilTemp[i] = (char *) calloc(sizeof(char), BUFSIZE + 1))) ReportError(Routine, 1); sprintf(KeyName, "MM5 SOIL TEMPERATURE FILE %d", i); GetInitString("METEOROLOGY", KeyName, "", VarStr, (unsigned long) BUFSIZE, Input); if (IsEmptyStr(VarStr)) ReportError(KeyName, 51); strcpy(InFiles->MM5SoilTemp[i], VarStr); } } if (!CopyDouble(&(MM5Map->Yorig), StrEnv[MM5_ext_north].VarStr, 1)) ReportError(StrEnv[MM5_ext_north].KeyName, 51); if (!CopyDouble(&(MM5Map->Xorig), StrEnv[MM5_ext_west].VarStr, 1)) ReportError(StrEnv[MM5_ext_west].KeyName, 51); if (!CopyInt(&(MM5Map->NY), StrEnv[MM5_rows].VarStr, 1)) ReportError(StrEnv[MM5_rows].KeyName, 51); if (!CopyInt(&(MM5Map->NX), StrEnv[MM5_cols].VarStr, 1)) ReportError(StrEnv[MM5_cols].KeyName, 51); if (!CopyFloat(&(MM5Map->DY), StrEnv[MM5_dy].VarStr, 1)) ReportError(StrEnv[MM5_dy].KeyName, 51); MM5Map->OffsetX = Round(((float) (MM5Map->Xorig - Map->Xorig)) / ((float) Map->DX)); MM5Map->OffsetY = Round(((float) (MM5Map->Yorig - Map->Yorig)) / ((float) Map->DY)); if (MM5Map->OffsetX > 0 || MM5Map->OffsetY < 0) ReportError("Input Options File", 31); printf("MM5 extreme north / south is %f %f \n", MM5Map->Yorig, MM5Map->Yorig - MM5Map->NY * MM5Map->DY); printf("MM5 extreme west / east is %f %f\n", MM5Map->Xorig, MM5Map->Xorig + MM5Map->NX * MM5Map->DY); printf("MM5 rows is %d \n", MM5Map->NY); printf("MM5 cols is %d \n", MM5Map->NX); printf("MM5 dy is %f \n", MM5Map->DY); printf("Temperature Map is %s\n", InFiles->MM5Temp); printf("Precip Map is %s\n", InFiles->MM5Precipitation); printf("wind Map is %s\n", InFiles->MM5Wind); printf("shortwave Map is %s\n", InFiles->MM5ShortWave); printf("humidity Map is %s\n", InFiles->MM5Humidity); printf("lapse Map is %s\n", InFiles->MM5Lapse); printf("terrain Map is %s\n", InFiles->MM5Terrain); printf("MM5 offset x is %d \n", MM5Map->OffsetX); printf("MM5 offset y is %d \n", MM5Map->OffsetY); printf("dhsvm extreme north / south is %f %f \n", Map->Yorig, Map->Yorig - Map->NY * Map->DY); printf("dhsvm extreme west / east is %f %f \n", Map->Xorig, Map->Xorig + Map->NX * Map->DY); printf("fail if %d > %d\n", (int) ((Map->NY + MM5Map->OffsetY) * Map->DY / MM5Map->DY), MM5Map->NY); printf("fail if %d > %d\n", (int) ((Map->NX - MM5Map->OffsetX) * Map->DX / MM5Map->DY), MM5Map->NX); if ((int) ((Map->NY + MM5Map->OffsetY) * Map->DY / MM5Map->DY) > MM5Map->NY || (int) ((Map->NX - MM5Map->OffsetX) * Map->DX / MM5Map->DY) > MM5Map->NX) ReportError("Input Options File", 31); }
/******************************************************************************* 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; } }
/******************************************************************************* 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 : *****************************************************************************/ void InitDump(LISTPTR Input, OPTIONSTRUCT * Options, MAPSIZE * Map, int MaxSoilLayers, int MaxVegLayers, int Dt, TOPOPIX ** TopoMap, DUMPSTRUCT * Dump, int *NGraphics, int **which_graphics) { char *Routine = "InitDump"; int i; int x; /* counter */ int y; /* counter */ int NImageVars; /* Number of different variables for which to dump images */ int NMapVars; /* Number of different variables for which to dump maps */ int temp_count; uchar **BasinMask; char sumoutfile[100]; STRINIENTRY StrEnv[] = { {"OUTPUT", "OUTPUT DIRECTORY", "", ""}, {"OUTPUT", "INITIAL STATE DIRECTORY", "", ""}, {"OUTPUT", "NUMBER OF OUTPUT PIXELS", "", ""}, {"OUTPUT", "NUMBER OF MODEL STATES", "", ""}, {"OUTPUT", "NUMBER OF MAP VARIABLES", "", ""}, {"OUTPUT", "NUMBER OF IMAGE VARIABLES", "", ""}, {"OUTPUT", "NUMBER OF GRAPHICS", "", ""}, {NULL, NULL, "", NULL}, }; printf("Initializing dump procedures\n"); /* Get the key-entry pairs from the input file */ for (i = 0; StrEnv[i].SectionName; i++) GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default, StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input); /* Assign the entries to the variables */ if (IsEmptyStr(StrEnv[output_path].VarStr)) ReportError(StrEnv[output_path].KeyName, 51); strcpy(Dump->Path, StrEnv[output_path].VarStr); // delete any previous failure_summary.txt file sprintf(sumoutfile, "%sfailure_summary.txt", Dump->Path); if (remove(sumoutfile) != -1) printf(" - removed old version of failure_summary.txt\n"); if (IsEmptyStr(StrEnv[initial_state_path].VarStr)) strcpy(Dump->InitStatePath, Dump->Path); strcpy(Dump->InitStatePath, StrEnv[initial_state_path].VarStr); if (IsEmptyStr(StrEnv[npixels].VarStr)) Dump->NPix = 0; else if (!CopyInt(&(Dump->NPix), StrEnv[npixels].VarStr, 1) || Dump->NPix < 0) ReportError(StrEnv[npixels].KeyName, 51); if (IsEmptyStr(StrEnv[nstates].VarStr)) Dump->NStates = 0; else if (!CopyInt(&(Dump->NStates), StrEnv[nstates].VarStr, 1)) ReportError(StrEnv[nstates].KeyName, 51); if (IsEmptyStr(StrEnv[nmapvars].VarStr)) NMapVars = 0; else if (!CopyInt(&NMapVars, StrEnv[nmapvars].VarStr, 1) || NMapVars < 0) ReportError(StrEnv[nmapvars].KeyName, 51); if (IsEmptyStr(StrEnv[nimagevars].VarStr)) NImageVars = 0; else if (!CopyInt(&NImageVars, StrEnv[nimagevars].VarStr, 1) || NImageVars < 0) ReportError(StrEnv[nimagevars].KeyName, 51); if (IsEmptyStr(StrEnv[ngraphics].VarStr)) *NGraphics = 0; else if (!CopyInt(NGraphics, StrEnv[ngraphics].VarStr, 1) || *NGraphics < 0) ReportError(StrEnv[ngraphics].KeyName, 51); if (Options->Extent == POINT) *NGraphics = 0; Dump->NMaps = NMapVars + NImageVars; // Open file for recording aggregated values for entire basin sprintf(Dump->Aggregate.FileName, "%sAggregated.Values", Dump->Path); OpenFile(&(Dump->Aggregate.FilePtr), Dump->Aggregate.FileName, "w", TRUE); // If specified, open file for recording aggregated sediment values for entire basin if (Options->Sediment) { sprintf(Dump->AggregateSediment.FileName, "%sAggregatedSediment.Values", Dump->Path); OpenFile(&(Dump->AggregateSediment.FilePtr), Dump->AggregateSediment.FileName, "w", TRUE); // Open file for recording mass balance for entire basin sprintf(Dump->SedBalance.FileName, "%sMassSediment.Balance", Dump->Path); OpenFile(&(Dump->SedBalance.FilePtr), Dump->SedBalance.FileName, "w", TRUE); } // Open file for recording mass balance for entire basin sprintf(Dump->Balance.FileName, "%sMass.Balance", Dump->Path); OpenFile(&(Dump->Balance.FilePtr), Dump->Balance.FileName, "w", TRUE); if (Options->Extent != POINT) { /* Read remaining information from dump info file */ if (Dump->NStates > 0) InitStateDump(Input, Dump->NStates, &(Dump->DState)); /* if Dump->NStates < 0, the state will be dumped every time step, this is done directly in ExecDump */ if (!(BasinMask = (uchar **) calloc(Map->NY, sizeof(uchar *)))) ReportError(Routine, 1); for (y = 0; y < Map->NY; y++) if (!(BasinMask[y] = (uchar *) calloc(Map->NX, sizeof(uchar)))) ReportError(Routine, 1); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) BasinMask[y][x] = TopoMap[y][x].Mask; if (Dump->NPix > 0) { temp_count = InitPixDump(Input, Map, BasinMask, Dump->Path, Dump->NPix, &(Dump->Pix), Options); if (temp_count == 0) { Dump->NPix = 0; printf("no candidate dump pixels accepted \n"); } else { Dump->NPix = temp_count; printf("total number of accepted dump pixels %d \n", Dump->NPix); } } for (y = 0; y < Map->NY; y++) free(BasinMask[y]); free(BasinMask); if (Dump->NMaps > 0) InitMapDump(Input, Map, MaxSoilLayers, MaxVegLayers, Dump->Path, Dump->NMaps, NMapVars, &(Dump->DMap)); if (NImageVars > 0) InitImageDump(Input, Dt, Map, MaxSoilLayers, MaxVegLayers, Dump->Path, Dump->NMaps, NImageVars, &(Dump->DMap)); if (*NGraphics > 0) InitGraphicsDump(Input, *NGraphics, &which_graphics); /* if no network open unit hydrograph file */ if (!(Options->HasNetwork)) { sprintf(Dump->Stream.FileName, "%sStream.Flow", Dump->Path); OpenFile(&(Dump->Stream.FilePtr), Dump->Stream.FileName, "w", TRUE); } } }
/******************************************************************************* 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: 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 : ********************************************************************************/ int InitSoilTable(SOILTABLE ** SType, LISTPTR Input, LAYER * Soil) { const char *Routine = "InitSoilTable"; int i; /* counter */ int j; /* counter */ int NSoils; /* Number of soil types */ char KeyName[thermal_capacity + 1][BUFSIZE + 1]; char *KeyStr[] = { "SOIL DESCRIPTION", "LATERAL CONDUCTIVITY", "EXPONENTIAL DECREASE", "DEPTH THRESHOLD", "MAXIMUM INFILTRATION", "CAPILLARY DRIVE", "SURFACE ALBEDO", "MANNINGS N", "NUMBER OF SOIL LAYERS", "POROSITY", "PORE SIZE DISTRIBUTION", "BUBBLING PRESSURE", "FIELD CAPACITY", "WILTING POINT", "BULK DENSITY", "VERTICAL CONDUCTIVITY", "THERMAL CONDUCTIVITY", "THERMAL CAPACITY" }; char SectionName[] = "SOILS"; char VarStr[thermal_capacity + 1][BUFSIZE + 1]; /* Get the number of different soil types */ GetInitString(SectionName, "NUMBER OF SOIL TYPES", "", VarStr[0], (unsigned long) BUFSIZE, Input); if (!CopyInt(&NSoils, VarStr[0], 1)) ReportError("NUMBER OF SOIL TYPES", 51); if (NSoils == 0) return NSoils; if (!(Soil->NLayers = (int *) calloc(NSoils, sizeof(int)))) ReportError((char *) Routine, 1); if (!(*SType = (SOILTABLE *) calloc(NSoils, sizeof(SOILTABLE)))) ReportError((char *) Routine, 1); /********** Read information and allocate memory for each soil type *********/ Soil->MaxLayers = 0; for (i = 0; i < NSoils; i++) { /* Read the key-entry pairs from the input file */ for (j = 0; j <= thermal_capacity; 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 (IsEmptyStr(VarStr[soil_description])) ReportError(KeyName[soil_description], 51); strcpy((*SType)[i].Desc, VarStr[soil_description]); (*SType)[i].Index = i; if (!CopyFloat(&((*SType)[i].KsLat), VarStr[lateral_ks], 1)) ReportError(KeyName[lateral_ks], 51); if (!CopyFloat(&((*SType)[i].KsLatExp), VarStr[exponent], 1)) ReportError(KeyName[exponent], 51); if (!CopyFloat(&((*SType)[i].DepthThresh), VarStr[depth_thresh], 1)) ReportError(KeyName[depth_thresh], 51); if (!CopyFloat(&((*SType)[i].MaxInfiltrationRate), VarStr[max_infiltration], 1)) ReportError(KeyName[max_infiltration], 51); if (!CopyFloat(&((*SType)[i].G_Infilt), VarStr[capillary_drive], 1)) ReportError(KeyName[capillary_drive], 51); if (!CopyFloat(&((*SType)[i].Albedo), VarStr[soil_albedo], 1)) ReportError(KeyName[soil_albedo], 51); if (!CopyInt(&(*SType)[i].NLayers, VarStr[number_of_layers], 1)) ReportError(KeyName[number_of_layers], 51); Soil->NLayers[i] = (*SType)[i].NLayers; if (!CopyFloat(&((*SType)[i].Manning), VarStr[manning], 1)) ReportError(KeyName[manning], 51); if (Soil->NLayers[i] > Soil->MaxLayers) Soil->MaxLayers = Soil->NLayers[i]; /* allocate memory for the soil layers */ if (!((*SType)[i].Porosity = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].PoreDist = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].Press = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].FCap = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].WP = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].Dens = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].Ks = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].KhDry = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].KhSol = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*SType)[i].Ch = (float *) calloc((*SType)[i].NLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!CopyFloat((*SType)[i].Porosity, VarStr[porosity], (*SType)[i].NLayers)) ReportError(KeyName[porosity], 51); if (!CopyFloat((*SType)[i].PoreDist, VarStr[pore_size], (*SType)[i].NLayers)) ReportError(KeyName[pore_size], 51); if (!CopyFloat((*SType)[i].Press, VarStr[bubbling_pressure], (*SType)[i].NLayers)) ReportError(KeyName[bubbling_pressure], 51); if (!CopyFloat((*SType)[i].FCap, VarStr[field_capacity], (*SType)[i].NLayers)) ReportError(KeyName[field_capacity], 51); if (!CopyFloat((*SType)[i].WP, VarStr[wilting_point], (*SType)[i].NLayers)) ReportError(KeyName[wilting_point], 51); if (!CopyFloat((*SType)[i].Dens, VarStr[bulk_density], (*SType)[i].NLayers)) ReportError(KeyName[bulk_density], 51); if (!CopyFloat((*SType)[i].Ks, VarStr[vertical_ks], (*SType)[i].NLayers)) ReportError(KeyName[vertical_ks], 51); if (!CopyFloat((*SType)[i].KhSol, VarStr[solids_thermal], (*SType)[i].NLayers)) ReportError(KeyName[solids_thermal], 51); if (!CopyFloat((*SType)[i].Ch, VarStr[thermal_capacity], (*SType)[i].NLayers)) ReportError(KeyName[thermal_capacity], 51); } for (i = 0; i < NSoils; i++) for (j = 0; j < (*SType)[i].NLayers; j++) { (*SType)[i].KhDry[j] = CalcKhDry((*SType)[i].Dens[j]); if (((*SType)[i].Porosity[j] < (*SType)[i].FCap[j]) || ((*SType)[i].Porosity[j] < (*SType)[i].WP[j]) || ((*SType)[i].FCap[j] < (*SType)[i].WP[j])) ReportError((*SType)[i].Desc, 11); } return NSoils; }
/******************************************************************************** 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 : ********************************************************************************/ int InitVegTable(VEGTABLE ** VType, LISTPTR Input, OPTIONSTRUCT * Options, LAYER * Veg) { const char *Routine = "InitVegTable"; int i; /* Counter */ int j; /* Counter */ float impervious; /* flag to check whether impervious layers are specified */ int NVegs; /* Number of vegetation types */ char KeyName[understory_monalb + 1][BUFSIZE + 1]; char *KeyStr[] = { "VEGETATION DESCRIPTION", "OVERSTORY PRESENT", "UNDERSTORY PRESENT", "FRACTIONAL COVERAGE", "HEMI FRACT COVERAGE", "TRUNK SPACE", "AERODYNAMIC ATTENUATION", "RADIATION ATTENUATION", "CLUMPING FACTOR", "LEAF ANGLE A", "LEAF ANGLE B", "SCATTERING PARAMETER", "MAX SNOW INT CAPACITY", "MASS RELEASE DRIP RATIO", "SNOW INTERCEPTION EFF", "IMPERVIOUS FRACTION", "DETENTION FRACTION", "DETENTION DECAY", "HEIGHT", "MAXIMUM RESISTANCE", "MINIMUM RESISTANCE", "MOISTURE THRESHOLD", "VAPOR PRESSURE DEFICIT", "RPC", "NUMBER OF ROOT ZONES", "ROOT ZONE DEPTHS", "OVERSTORY ROOT FRACTION", "UNDERSTORY ROOT FRACTION", "OVERSTORY MONTHLY LAI", "UNDERSTORY MONTHLY LAI", "OVERSTORY MONTHLY ALB", "UNDERSTORY MONTHLY ALB" }; char SectionName[] = "VEGETATION"; char VarStr[understory_monalb + 1][BUFSIZE + 1]; /* Get the number of different vegetation types */ GetInitString(SectionName, "NUMBER OF VEGETATION TYPES", "", VarStr[0], (unsigned long) BUFSIZE, Input); if (!CopyInt(&NVegs, VarStr[0], 1)) ReportError("NUMBER OF VEGETATION TYPES", 51); if (NVegs == 0) return NVegs; if (!(Veg->NLayers = (int *) calloc(NVegs, sizeof(int)))) ReportError((char *) Routine, 1); if (!(*VType = (VEGTABLE *) calloc(NVegs, sizeof(VEGTABLE)))) ReportError((char *) Routine, 1); /******* Read information and allocate memory for each vegetation type ******/ Veg->MaxLayers = 0; impervious = 0.0; for (i = 0; i < NVegs; i++) { /* Read the key-entry pairs from the input file */ for (j = 0; j <= understory_monalb; 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 (IsEmptyStr(VarStr[veg_description])) ReportError(KeyName[veg_description], 51); strcpy((*VType)[i].Desc, VarStr[veg_description]); MakeKeyString(VarStr[veg_description]); /* basically makes the string all uppercase and removed spaces so it is easier to compare */ if (strncmp(VarStr[veg_description], "GLACIER", strlen("GLACIER")) == 0) { (*VType)[i].Index = GLACIER; } else (*VType)[i].Index = i; (*VType)[i].NVegLayers = 0; if (strncmp(VarStr[overstory], "TRUE", 4) == 0) { (*VType)[i].OverStory = TRUE; ((*VType)[i].NVegLayers)++; } else if (strncmp(VarStr[overstory], "FALSE", 5) == 0) (*VType)[i].OverStory = FALSE; else ReportError(KeyName[overstory], 51); if (strncmp(VarStr[understory], "TRUE", 4) == 0) { (*VType)[i].UnderStory = TRUE; ((*VType)[i].NVegLayers)++; } else if (strncmp(VarStr[understory], "FALSE", 5) == 0) (*VType)[i].UnderStory = FALSE; else ReportError(KeyName[understory], 51); Veg->NLayers[i] = (*VType)[i].NVegLayers; if ((*VType)[i].NVegLayers > Veg->MaxLayers) Veg->MaxLayers = (*VType)[i].NVegLayers; if (!CopyInt(&(*VType)[i].NSoilLayers, VarStr[number_of_root_zones], 1)) ReportError(KeyName[number_of_root_zones], 51); if (!CopyFloat(&((*VType)[i].ImpervFrac), VarStr[imperv_frac], 1)) ReportError(KeyName[imperv_frac], 51); impervious += (*VType)[i].ImpervFrac; if (!CopyFloat(&((*VType)[i].DetentionFrac), VarStr[detention_frac], 1)) ReportError(KeyName[detention_frac], 51); if (!CopyFloat(&((*VType)[i].DetentionDecay), VarStr[detention_decay], 1)) ReportError(KeyName[detention_decay], 51); /* allocate memory for the vegetation layers */ if (!((*VType)[i].Fract = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (Options->CanopyRadAtt == VARIABLE) { if (!((*VType)[i].HemiFract = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); } else { (*VType)[i].HemiFract = NULL; } if (!((*VType)[i].Height = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].RsMax = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].RsMin = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].MoistThres = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].VpdThres = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].Rpc = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].Albedo = (float *) calloc(((*VType)[i].NVegLayers + 1), sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].MaxInt = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].LAI = (float *) calloc((*VType)[i].NVegLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].RootFract = (float **) calloc((*VType)[i].NVegLayers, sizeof(float *)))) ReportError((char *) Routine, 1); for (j = 0; j < (*VType)[i].NVegLayers; j++) { if (!((*VType)[i].RootFract[j] = (float *) calloc((*VType)[i].NSoilLayers, sizeof(float)))) ReportError((char *) Routine, 1); } if (!((*VType)[i].RootDepth = (float *) calloc((*VType)[i].NSoilLayers, sizeof(float)))) ReportError((char *) Routine, 1); if (!((*VType)[i].LAIMonthly = (float **) calloc((*VType)[i].NVegLayers, sizeof(float *)))) ReportError((char *) Routine, 1); for (j = 0; j < (*VType)[i].NVegLayers; j++) { if (!((*VType)[i].LAIMonthly[j] = (float *) calloc(12, sizeof(float)))) ReportError((char *) Routine, 1); } if (!((*VType)[i].AlbedoMonthly = (float **) calloc((*VType)[i].NVegLayers, sizeof(float *)))) ReportError((char *) Routine, 1); for (j = 0; j < (*VType)[i].NVegLayers; j++) { if (!((*VType)[i].AlbedoMonthly[j] = (float *) calloc(12, sizeof(float)))) ReportError((char *) Routine, 1); } /* assign the entries to the appropriate variables */ /* allocation of zero memory is not supported on some compilers */ if ((*VType)[i].OverStory == TRUE) { if (!CopyFloat(&((*VType)[i].Fract[0]), VarStr[fraction], 1)) ReportError(KeyName[fraction], 51); if (Options->CanopyRadAtt == VARIABLE) { if (!CopyFloat(&((*VType)[i].HemiFract[0]), VarStr[hemifraction], 1)) ReportError(KeyName[hemifraction], 51); if (!CopyFloat(&((*VType)[i].ClumpingFactor),VarStr[clumping_factor], 1)) ReportError(KeyName[clumping_factor], 51); if (!CopyFloat(&((*VType)[i].LeafAngleA), VarStr[leaf_angle_a], 1)) ReportError(KeyName[leaf_angle_a], 51); if (!CopyFloat(&((*VType)[i].LeafAngleB), VarStr[leaf_angle_b], 1)) ReportError(KeyName[leaf_angle_b], 51); if (!CopyFloat(&((*VType)[i].Scat), VarStr[scat], 1)) ReportError(KeyName[scat], 51); (*VType)[i].Atten = NOT_APPLICABLE; } else if (Options->CanopyRadAtt == FIXED) { if (!CopyFloat(&((*VType)[i].Atten), VarStr[radiation_att], 1)) ReportError(KeyName[radiation_att], 51); (*VType)[i].ClumpingFactor = NOT_APPLICABLE; (*VType)[i].Scat = NOT_APPLICABLE; (*VType)[i].LeafAngleA = NOT_APPLICABLE; (*VType)[i].LeafAngleB = NOT_APPLICABLE; } if (!CopyFloat(&((*VType)[i].Trunk), VarStr[trunk_space], 1)) ReportError(KeyName[trunk_space], 51); if (!CopyFloat(&((*VType)[i].Cn), VarStr[aerodynamic_att], 1)) ReportError(KeyName[aerodynamic_att], 51); if (!CopyFloat(&((*VType)[i].MaxSnowInt), VarStr[snow_int_cap], 1)) ReportError(KeyName[snow_int_cap], 51); if (!CopyFloat(&((*VType)[i].MDRatio), VarStr[mass_drip_ratio], 1)) ReportError(KeyName[mass_drip_ratio], 51); if (!CopyFloat(&((*VType)[i].SnowIntEff), VarStr[snow_int_eff], 1)) ReportError(KeyName[snow_int_eff], 51); if (!CopyFloat((*VType)[i].RootFract[0], VarStr[overstory_fraction], (*VType)[i].NSoilLayers)) ReportError(KeyName[overstory_fraction], 51); if (!CopyFloat((*VType)[i].LAIMonthly[0], VarStr[overstory_monlai], 12)) ReportError(KeyName[overstory_monlai], 51); if (!CopyFloat((*VType)[i].AlbedoMonthly[0], VarStr[overstory_monalb], 12)) ReportError(KeyName[overstory_monalb], 51); if ((*VType)[i].UnderStory == TRUE) { (*VType)[i].Fract[1] = 1.0; if (!CopyFloat((*VType)[i].RootFract[1], VarStr[understory_fraction], (*VType)[i].NSoilLayers)) ReportError(KeyName[understory_fraction], 51); if (!CopyFloat((*VType)[i].LAIMonthly[1], VarStr[understory_monlai], 12)) ReportError(KeyName[understory_monlai], 51); if (!CopyFloat((*VType)[i].AlbedoMonthly[1], VarStr[understory_monalb], 12)) ReportError(KeyName[understory_monalb], 51); } } else { if ((*VType)[i].UnderStory == TRUE) { (*VType)[i].Fract[0] = 1.0; if (!CopyFloat((*VType)[i].RootFract[0], VarStr[understory_fraction], (*VType)[i].NSoilLayers)) ReportError(KeyName[understory_fraction], 51); if (!CopyFloat((*VType)[i].LAIMonthly[0], VarStr[understory_monlai], 12)) ReportError(KeyName[understory_monlai], 51); if (!CopyFloat((*VType)[i].AlbedoMonthly[0], VarStr[understory_monalb], 12)) ReportError(KeyName[understory_monalb], 51); } (*VType)[i].Trunk = NOT_APPLICABLE; (*VType)[i].Cn = NOT_APPLICABLE; (*VType)[i].Atten = NOT_APPLICABLE; (*VType)[i].ClumpingFactor = NOT_APPLICABLE; } if (!CopyFloat((*VType)[i].Height, VarStr[height], (*VType)[i].NVegLayers)) ReportError(KeyName[height], 51); if (!CopyFloat((*VType)[i].RsMax, VarStr[max_resistance], (*VType)[i].NVegLayers)) ReportError(KeyName[max_resistance], 51); if (!CopyFloat((*VType)[i].RsMin, VarStr[min_resistance], (*VType)[i].NVegLayers)) ReportError(KeyName[min_resistance], 51); if (!CopyFloat((*VType)[i].MoistThres, VarStr[moisture_threshold], (*VType)[i].NVegLayers)) ReportError(KeyName[moisture_threshold], 51); if (!CopyFloat((*VType)[i].VpdThres, VarStr[vpd], (*VType)[i].NVegLayers)) ReportError(KeyName[vpd], 51); if (!CopyFloat((*VType)[i].Rpc, VarStr[rpc], (*VType)[i].NVegLayers)) ReportError(KeyName[rpc], 51); if (!CopyFloat((*VType)[i].RootDepth, VarStr[root_zone_depth], (*VType)[i].NSoilLayers)) ReportError(KeyName[root_zone_depth], 51); /* Calculate the wind speed profiles and the aerodynamical resistances for each layer. The values are normalized for a reference height wind speed of 1 m/s, and are adjusted each timestep using actual reference height wind speeds */ CalcAerodynamic((*VType)[i].NVegLayers, (*VType)[i].OverStory, (*VType)[i].Cn, (*VType)[i].Height, (*VType)[i].Trunk, (*VType)[i].U, &((*VType)[i].USnow), (*VType)[i].Ra, &((*VType)[i].RaSnow)); } if (impervious) { GetInitString(SectionName, "IMPERVIOUS SURFACE ROUTING FILE", "", VarStr[0], (unsigned long) BUFSIZE, Input); if (IsEmptyStr(VarStr[0])) ReportError("IMPERVIOUS SURFACE ROUTING FILE", 51); strcpy(Options->ImperviousFilePath, VarStr[veg_description]); } return NVegs; }
/***************************************************************************** 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 : Make sure order in settings.h matches list of keys here Some modifications for input of monthly atmospheric parameters for soil chemistry model, MWW -sc 10/2005 *****************************************************************************/ void InitConstants(LISTPTR Input, OPTIONSTRUCT * Options, MAPSIZE * Map, SOLARGEOMETRY * SolarGeo, TIMESTRUCT * Time, BASINWIDE * Basinwide) { // const char *Routine = "InitConstants"; int i, j; /* counter */ double PointModelX; /* X-coordinate for POINT model mode */ double PointModelY; /* Y-coordinate for POINT model mode */ float TimeStep; /* Timestep in hours */ DATE End; /* End of run */ DATE Start; /* Start of run */ STRINIENTRY StrEnv[] = { {"OPTIONS", "INPUTFILEVERSION", "", ""}, {"OPTIONS", "FORMAT", "", ""}, {"OPTIONS", "EXTENT", "", ""}, {"OPTIONS", "GRADIENT", "", ""}, {"OPTIONS", "FLOW ROUTING", "", ""}, {"OPTIONS", "SENSIBLE HEAT FLUX", "", ""}, {"OPTIONS", "STREAM TEMPERATURE", "", ""}, {"OPTIONS", "GROUNDWATER", "" , ""}, {"OPTIONS", "CHEMISTRY", "" , ""}, {"OPTIONS", "GLACIER MOVEMENT", "" , ""}, {"OPTIONS", "CHANNEL INFILTRATION", "" , ""}, {"OPTIONS", "FRACTIONAL ROUTING", "" , ""}, {"OPTIONS", "INTERPOLATION", "", ""}, {"OPTIONS", "MM5", "", ""}, {"OPTIONS", "QPF", "", ""}, {"OPTIONS", "PRISM", "", ""}, {"OPTIONS", "CANOPY RADIATION ATTENUATION MODE", "", ""}, {"OPTIONS", "SHADING", "", ""}, {"OPTIONS", "SNOTEL", "", ""}, {"OPTIONS", "OUTSIDE", "", ""}, {"OPTIONS", "RHOVERRIDE", "", ""}, {"OPTIONS", "PRECIPITATION SOURCE", "", ""}, {"OPTIONS", "WIND SOURCE", "", ""}, {"OPTIONS", "TEMPERATURE LAPSE RATE", "", ""}, {"OPTIONS", "PRECIPITATION LAPSE RATE", "", ""}, {"OPTIONS", "CRESSMAN RADIUS", "", ""}, {"OPTIONS", "CRESSMAN STATIONS", "", ""}, {"OPTIONS", "PRISM DATA PATH", "", ""}, {"OPTIONS", "PRISM DATA EXTENSION", "", ""}, {"OPTIONS", "SHADING DATA PATH", "", ""}, {"OPTIONS", "SHADING DATA EXTENSION", "", ""}, {"OPTIONS", "SKYVIEW DATA PATH", "", ""}, {"OPTIONS", "INITIAL STATE PATH", "", ""}, {"AREA", "COORDINATE SYSTEM", "", ""}, {"AREA", "EXTREME NORTH", "", ""}, {"AREA", "EXTREME WEST", "", ""}, {"AREA", "CENTER LATITUDE", "", ""}, {"AREA", "CENTER LONGITUDE", "", ""}, {"AREA", "TIME ZONE MERIDIAN", "", ""}, {"AREA", "NUMBER OF ROWS", "", ""}, {"AREA", "NUMBER OF COLUMNS", "", ""}, {"AREA", "GRID SPACING", "", ""}, {"AREA", "POINT NORTH", "", ""}, {"AREA", "POINT EAST", "", ""}, {"TIME", "TIME STEP", "", ""}, {"TIME", "MODEL START", "", ""}, {"TIME", "MODEL END", "", ""}, {"CONSTANTS", "GROUND ROUGHNESS", "", ""}, {"CONSTANTS", "SNOW ROUGHNESS", "", ""}, {"CONSTANTS", "RAIN THRESHOLD", "", ""}, {"CONSTANTS", "SNOW THRESHOLD", "", ""}, {"CONSTANTS", "SNOW WATER CAPACITY", "", ""}, {"CONSTANTS", "REFERENCE HEIGHT", "", ""}, {"CONSTANTS", "RAIN LAI MULTIPLIER", "", ""}, {"CONSTANTS", "SNOW LAI MULTIPLIER", "", ""}, {"CONSTANTS", "MIN INTERCEPTED SNOW", "", ""}, {"CONSTANTS", "OUTSIDE BASIN VALUE", "", ""}, {"CONSTANTS", "GLACIER CREEP ACTIVATION ENERGY", "", ""}, {"CONSTANTS", "GLEN CONSTANT", "", ""}, {"CONSTANTS", "MAXIMUM GLACIER FLUX FRACTION", "", ""}, {"CONSTANTS", "TEMPERATURE LAPSE RATE", "", ""}, {"CONSTANTS", "PRECIPITATION LAPSE RATE", "", ""}, {"CONSTANTS", "DEPTH RATIO", "", ""}, {"CONSTANTS", "WIND ATTENUATION FACTOR", "", ""}, {"CONSTANTS", "RAD ATTENUATION FACTOR", "", ""}, {"CONSTANTS", "MINIMUM SEGMENT ORDER", "", ""}, {"CHEMISTRY", "METABOLIC DOC DECOMPOSITION RATE", "", ""}, {"CHEMISTRY", "STRUCTURAL DOC DECOMPOSITION RATE", "", ""}, {"CHEMISTRY", "DECOMPOSITION RATE CONSTANT OF DOC", "", ""}, {"CHEMISTRY", "MAXIMUM DOC SORPTION COEFFICIENT", "", ""}, {"CHEMISTRY", "C:N FOR SORBED DOM", "", ""}, {"CHEMISTRY", "C:N FOR MICROBIAL DECOMP OF DOM", "", ""}, {"CHEMISTRY", "BACKGROUND CATIONS", "", ""}, {"CHEMISTRY", "NITRIFICATION TEMPERATURE FACTOR", "", ""}, {"CHEMISTRY", "FREE AIR CO2 DIFFUSION COEFFICIENT", "", ""}, {"CHEMISTRY", "FREE AIR O2 DIFFUSION COEFFICIENT", "", ""}, {"CHEMISTRY", "MASS TRANSFER COEFFICIENT OF DISSOLVED CO2", "", ""}, {"CHEMISTRY", "MASS TRANSFER COEFFICIENT OF DISSOLVED O2", "", ""}, {"CHEMISTRY", "DENITRIFICATION SATURATION THRESHOLD", "", ""}, {"CHEMISTRY", "NITRATE REDUCTION HALF SATURATION FRACTION", "", ""}, {"CHEMISTRY", "OXYGEN CONCENTRATION REACTION COEFFICIENT", "", ""}, {"CHEMISTRY", "SUSPENDED DOC MINERALIZATION CONSTANT", "", ""}, {"CHEMISTRY", "SUSPENDED DON HYDROLYSIS RATE", "", ""}, {"CHEMISTRY", "SUSPENDED AMMONIUM DECOMPOSITION RATE", "", ""}, {"CHEMISTRY", "SUSPENDED NITRIFICATION RATE", "", ""}, {"CHEMISTRY", "ATMOSPHERIC CO2 CONCENTRATION", "", ""}, {"CHEMISTRY", "ATMOSPHERIC DOC CONCENTRATION", "", ""}, {"CHEMISTRY", "ATMOSPHERIC DON CONCENTRATION", "", ""}, {"CHEMISTRY", "ATMOSPHERIC NH4 CONCENTRATION", "", ""}, {"CHEMISTRY", "ATMOSPHERIC NO3 CONCENTRATION", "", ""}, {"CHEMISTRY", "ATMOSPHERIC NO2 CONCENTRATION", "", ""}, {NULL, NULL, "", NULL} }; /* Read the key-entry pairs from the input file */ for (i = 0; StrEnv[i].SectionName; i++) GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default, StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input); /**************** Determine model options ****************/ /* Determine file format to be used */ if (strncmp(StrEnv[inputfileversion].VarStr, "045", 3) != 0) { printf("\n\n****************************************\nERROR LOADING INPUT FILE, WRONG VERSION\n"); printf("Please make sure that the inputfileversion field in the [OPTIONS] section of the config file matches the INPUT_FILE_VERSION constant set in settings.h\n"); printf("\nExpected INPUT_FILE_VERSION="); printf(INPUT_FILE_VERSION); printf("\tValue in Input file=%s",StrEnv[inputfileversion].VarStr); ReportError(StrEnv[inputfileversion].KeyName,51); } if (strncmp(StrEnv[format].VarStr, "BIN", 3) == 0) Options->FileFormat = BIN; else if (strncmp(StrEnv[format].VarStr, "NETCDF", 3) == 0) Options->FileFormat = NETCDF; else if (strncmp(StrEnv[format].VarStr, "BYTESWAP", 3) == 0) Options->FileFormat = BYTESWAP; else ReportError(StrEnv[format].KeyName, 51); /* Determine whether the model should be run in POINT mode or in BASIN mode. If in POINT mode also read which pixel to model */ if (strncmp(StrEnv[extent].VarStr, "POINT", 5) == 0) { Options->Extent = POINT; Options->HasNetwork = FALSE; } else if (strncmp(StrEnv[extent].VarStr, "BASIN", 5) == 0) { Options->Extent = BASIN; } else ReportError(StrEnv[extent].KeyName, 51); /* Determine how the flow gradient should be calculated */ if (Options->Extent != POINT) { if (strncmp(StrEnv[gradient].VarStr, "TOPO", 4) == 0) Options->FlowGradient = TOPOGRAPHY; else if (strncmp(StrEnv[gradient].VarStr, "WATER", 5) == 0) Options->FlowGradient = WATERTABLE; else ReportError(StrEnv[gradient].KeyName, 51); } else Options->FlowGradient = NOT_APPLICABLE; /* Determine what meterological interpolation to use */ if (strncmp(StrEnv[interpolation].VarStr, "INVDIST", 7) == 0) Options->Interpolation = INVDIST; else if (strncmp(StrEnv[interpolation].VarStr, "NEAREST", 7) == 0) Options->Interpolation = NEAREST; else if (strncmp(StrEnv[interpolation].VarStr, "VARCRESS", 8) == 0) Options->Interpolation = VARCRESS; else ReportError(StrEnv[interpolation].KeyName, 51); /* if VARIABLE CRESTMAN interpolation then get parameters */ if (Options->Interpolation == VARCRESS) { if (!CopyInt(&(Options->CressRadius), StrEnv[cressman_radius].VarStr, 1)) ReportError(StrEnv[cressman_radius].KeyName, 51); if (!CopyInt (&(Options->CressStations), StrEnv[cressman_stations].VarStr, 1)) ReportError(StrEnv[cressman_stations].KeyName, 51); } /* Determine whether a road/network is imposed on the model area */ if (Options->Extent != POINT) { if (strncmp(StrEnv[flow_routing].VarStr, "NETWORK", 7) == 0) Options->HasNetwork = TRUE; else if (strncmp(StrEnv[flow_routing].VarStr, "UNIT", 4) == 0) Options->HasNetwork = FALSE; else ReportError(StrEnv[flow_routing].KeyName, 51); } else Options->HasNetwork = FALSE; /* Determine whether a sensible heat flux should be calculated */ if (strncmp(StrEnv[sensible_heat_flux].VarStr, "TRUE", 4) == 0) Options->HeatFlux = TRUE; else if (strncmp(StrEnv[sensible_heat_flux].VarStr, "FALSE", 5) == 0) Options->HeatFlux = FALSE; else ReportError(StrEnv[sensible_heat_flux].KeyName, 51); /* Determine whether or not calculate Stream Temperature MWW 08112004 */ if (strncmp(StrEnv[stream_temperature].VarStr, "TRUE", 4) == 0) Options->StreamTemp = TRUE; else if (strncmp(StrEnv[stream_temperature].VarStr, "FALSE", 5) == 0) Options->StreamTemp = FALSE; else ReportError(StrEnv[stream_temperature].KeyName, 51); /* determine if deeper groundwater is represented */ if (strncmp(StrEnv[groundwater].VarStr, "TRUE", 4) == 0) Options->Groundwater = TRUE; else if (strncmp(StrEnv[groundwater].VarStr, "FALSE", 5) == 0) Options->Groundwater = FALSE; else ReportError(StrEnv[groundwater].KeyName, 51); /* determine if soil chemistry is incorporated */ if (strncmp(StrEnv[chemistry].VarStr, "TRUE", 4) == 0) Options->Chemistry = TRUE; else if (strncmp(StrEnv[chemistry].VarStr, "FALSE", 5) == 0) Options->Chemistry = FALSE; else ReportError(StrEnv[chemistry].KeyName, 51); /* ALLOW GLACIERS TO MOVE ? */ if (strncmp(StrEnv[glacier_movement].VarStr, "TRUE", 4) == 0) Options->GlacierMove = TRUE; else if (strncmp(StrEnv[glacier_movement].VarStr, "FALSE", 5) == 0) Options->GlacierMove = FALSE; else ReportError(StrEnv[glacier_movement].KeyName, 51); /* determine if Channel Infiltration is allowed */ if (strncmp(StrEnv[channel_infiltration].VarStr, "TRUE", 4) == 0) Options->ChannelInfiltration = TRUE; else if (strncmp(StrEnv[channel_infiltration].VarStr, "FALSE", 5) == 0) Options->ChannelInfiltration = FALSE; else ReportError(StrEnv[channel_infiltration].KeyName, 51); /* determine if Fractional Routing is allowed */ if (strncmp(StrEnv[fractional_routing].VarStr, "TRUE", 4) == 0) Options->FractionalRouting = TRUE; else if (strncmp(StrEnv[fractional_routing].VarStr, "FALSE", 5) == 0) Options->FractionalRouting = FALSE; else ReportError(StrEnv[fractional_routing].KeyName, 51); /* Determine whether the mm5 interface should be used */ if (strncmp(StrEnv[mm5].VarStr, "TRUE", 4) == 0) Options->MM5 = TRUE; else if (strncmp(StrEnv[mm5].VarStr, "FALSE", 5) == 0) Options->MM5 = FALSE; else ReportError(StrEnv[mm5].KeyName, 51); /* Determine whether the QPF override should be used on the MM5 fields */ if (strncmp(StrEnv[qpf].VarStr, "TRUE", 4) == 0) Options->QPF = TRUE; else if (strncmp(StrEnv[qpf].VarStr, "FALSE", 5) == 0) Options->QPF = FALSE; else ReportError(StrEnv[qpf].KeyName, 51); /* Determine if PRISM maps will be used to interpolate precip fields */ if (strncmp(StrEnv[prism].VarStr, "TRUE", 4) == 0) Options->Prism = TRUE; else if (strncmp(StrEnv[prism].VarStr, "FALSE", 5) == 0) Options->Prism = FALSE; else ReportError(StrEnv[prism].KeyName, 51); /* Determine the kinf of canopy radiation attenuation to be used */ if (strncmp(StrEnv[canopy_radatt].VarStr, "FIXED", 3) == 0) Options->CanopyRadAtt = FIXED; else if (strncmp(StrEnv[canopy_radatt].VarStr, "VARIABLE", 3) == 0) Options->CanopyRadAtt = VARIABLE; else ReportError(StrEnv[canopy_radatt].KeyName, 51); /* Determine if solar shading maps will be used */ if (strncmp(StrEnv[shading].VarStr, "TRUE", 4) == 0) Options->Shading = TRUE; else if (strncmp(StrEnv[shading].VarStr, "FALSE", 5) == 0) Options->Shading = FALSE; else ReportError(StrEnv[shading].KeyName, 51); if (Options->MM5 == TRUE && Options->Prism == TRUE && Options->QPF == FALSE) ReportError(StrEnv[prism].KeyName, 51); /* Determine if Snotel test is called for */ if (strncmp(StrEnv[snotel].VarStr, "TRUE", 4) == 0) Options->Snotel = TRUE; else if (strncmp(StrEnv[snotel].VarStr, "FALSE", 5) == 0) Options->Snotel = FALSE; else ReportError(StrEnv[snotel].KeyName, 51); /* Determine if listed met stations outside bounding box are used */ if (strncmp(StrEnv[outside].VarStr, "TRUE", 4) == 0) Options->Outside = TRUE; else if (strncmp(StrEnv[outside].VarStr, "FALSE", 5) == 0) Options->Outside = FALSE; else ReportError(StrEnv[outside].KeyName, 51); if (Options->Prism == TRUE) { if (IsEmptyStr(StrEnv[prism_data_path].VarStr)) ReportError(StrEnv[prism_data_path].KeyName, 51); strcpy(Options->PrismDataPath, StrEnv[prism_data_path].VarStr); if (IsEmptyStr(StrEnv[prism_data_ext].VarStr)) ReportError(StrEnv[prism_data_ext].KeyName, 51); strcpy(Options->PrismDataExt, StrEnv[prism_data_ext].VarStr); } if (Options->Shading == TRUE) { if (IsEmptyStr(StrEnv[shading_data_path].VarStr)) ReportError(StrEnv[shading_data_path].KeyName, 51); strcpy(Options->ShadingDataPath, StrEnv[shading_data_path].VarStr); if (IsEmptyStr(StrEnv[shading_data_ext].VarStr)) ReportError(StrEnv[shading_data_ext].KeyName, 51); strcpy(Options->ShadingDataExt, StrEnv[shading_data_ext].VarStr); if (IsEmptyStr(StrEnv[skyview_data_path].VarStr)) ReportError(StrEnv[skyview_data_path].KeyName, 51); strcpy(Options->SkyViewDataPath, StrEnv[skyview_data_path].VarStr); } /* path to inital state files */ if (IsEmptyStr(StrEnv[initial_state_path].VarStr)) ReportError(StrEnv[initial_state_path].KeyName, 51); strcpy(Options->StartStatePath, StrEnv[initial_state_path].VarStr); /* Determine if rh override is used */ if (strncmp(StrEnv[rhoverride].VarStr, "TRUE", 4) == 0) Options->Rhoverride = TRUE; else if (strncmp(StrEnv[rhoverride].VarStr, "FALSE", 5) == 0) Options->Rhoverride = FALSE; else ReportError(StrEnv[rhoverride].KeyName, 51); /* The other met options are only of importance if MM5 is FALSE */ if (Options->MM5 == TRUE) { Options->PrecipType = NOT_APPLICABLE; Options->WindSource = NOT_APPLICABLE; Options->PrecipLapse = NOT_APPLICABLE; Options->TempLapse = NOT_APPLICABLE; if (Options->QPF == TRUE) Options->PrecipType = STATION; if (Options->QPF == TRUE && Options->Prism == FALSE) Options->PrecipLapse = CONSTANT; } else { /* Determine the type of precipitation data that the model will use */ if (strncmp(StrEnv[precipitation_source].VarStr, "RADAR", 5) == 0) Options->PrecipType = RADAR; else if (strncmp(StrEnv[precipitation_source].VarStr, "STATION", 7) == 0) Options->PrecipType = STATION; else ReportError(StrEnv[precipitation_source].KeyName, 51); /* Determine the type of wind data that the model will use */ if (strncmp(StrEnv[wind_source].VarStr, "MODEL", 5) == 0) Options->WindSource = MODEL; else if (strncmp(StrEnv[wind_source].VarStr, "STATION", 7) == 0) Options->WindSource = STATION; else ReportError(StrEnv[wind_source].KeyName, 51); /* Determine the type of temperature lapse rate */ if (strncmp(StrEnv[temp_lapse].VarStr, "CONSTANT", 8) == 0) { Options->TempLapse = CONSTANT; } else if (strncmp(StrEnv[temp_lapse].VarStr, "VARIABLE", 8) == 0) { Options->TempLapse = VARIABLE; } else if (strncmp(StrEnv[temp_lapse].VarStr, "MONTHLY", 7) == 0) { Options->TempLapse = MONTHLY; } else { ReportError(StrEnv[temp_lapse].KeyName, 51); } /* Determine the type of precipitation lapse rate */ if (strncmp(StrEnv[precip_lapse].VarStr, "CONSTANT", 8) == 0) Options->PrecipLapse = CONSTANT; else if (strncmp(StrEnv[precip_lapse].VarStr, "MAP", 3) == 0) Options->PrecipLapse = MAP; else if (strncmp(StrEnv[precip_lapse].VarStr, "VARIABLE", 8) == 0) Options->PrecipLapse = VARIABLE; else if (strncmp(StrEnv[precip_lapse].VarStr, "MONTHLY", 7) == 0) Options->PrecipLapse = MONTHLY; else ReportError(StrEnv[precip_lapse].KeyName, 51); } /**************** Determine areal extent ****************/ if (IsEmptyStr(StrEnv[coordinate_system].VarStr)) ReportError(StrEnv[coordinate_system].KeyName, 51); strcpy(Map->System, StrEnv[coordinate_system].VarStr); if (!CopyDouble(&(Map->Yorig), StrEnv[extreme_north].VarStr, 1)) ReportError(StrEnv[extreme_north].KeyName, 51); if (!CopyDouble(&(Map->Xorig), StrEnv[extreme_west].VarStr, 1)) ReportError(StrEnv[extreme_west].KeyName, 51); if (!CopyFloat(&(SolarGeo->Latitude), StrEnv[center_latitude].VarStr, 1)) ReportError(StrEnv[center_latitude].KeyName, 51); SolarGeo->Latitude *= (float) RADPDEG; if (!CopyFloat(&(SolarGeo->Longitude), StrEnv[center_longitude].VarStr, 1)) ReportError(StrEnv[center_longitude].KeyName, 51); SolarGeo->Longitude *= (float) RADPDEG; if (!CopyFloat(&(SolarGeo->StandardMeridian), StrEnv[time_zone_meridian].VarStr, 1)) ReportError(StrEnv[time_zone_meridian].KeyName, 51); SolarGeo->StandardMeridian *= (float) RADPDEG; if (!CopyInt(&(Map->NY), StrEnv[number_of_rows].VarStr, 1)) ReportError(StrEnv[number_of_rows].KeyName, 51); if (!CopyInt(&(Map->NX), StrEnv[number_of_columns].VarStr, 1)) ReportError(StrEnv[number_of_columns].KeyName, 51); if (!CopyFloat(&(Map->DY), StrEnv[grid_spacing].VarStr, 1)) ReportError(StrEnv[grid_spacing].KeyName, 51); Map->DX = Map->DY; Map->DXY = (float) sqrt(Map->DX * Map->DX + Map->DY * Map->DY); Map->X = 0; Map->Y = 0; Map->OffsetX = 0; Map->OffsetY = 0; #if NDIRS == 4 Map->xneighbor[0] = 0; Map->yneighbor[0] = -1; /* N (0 rads) */ Map->xneighbor[1] = 1; Map->yneighbor[1] = 0; /* E (PI/2 rads)*/ Map->xneighbor[2] = 0; Map->yneighbor[2] = 1; /* S (PI rads)*/ Map->xneighbor[3] = -1; Map->yneighbor[3] = 0; /* W (3PI/2 rads or -PI/2 rads)*/ #elif NDIRS == 8 Map->xneighbor[0] = 0; /*--------------------------*/ Map->yneighbor[0] = -1; /* N */ Map->xneighbor[1] = 1; Map->yneighbor[1] = -1; /* NE */ Map->xneighbor[2] = 1; Map->yneighbor[2] = 0; /* E */ Map->xneighbor[3] = 1; Map->yneighbor[3] = 1; /* SE */ Map->xneighbor[4] = 0; Map->yneighbor[4] = 1; /* S */ Map->xneighbor[5] = -1; Map->yneighbor[5] = 1; /* SW */ Map->xneighbor[6] = -1; Map->yneighbor[6] = 0; /* W */ Map->xneighbor[7] = -1; Map->yneighbor[7] = -1; /* NW */ #endif if (Options->Extent == POINT) { if (!CopyDouble(&PointModelY, StrEnv[point_north].VarStr, 1)) ReportError(StrEnv[point_north].KeyName, 51); if (!CopyDouble(&PointModelX, StrEnv[point_east].VarStr, 1)) ReportError(StrEnv[point_east].KeyName, 51); Options->PointY = Round(((Map->Yorig - 0.5 * Map->DY) - PointModelY) / Map->DY); Options->PointX = Round((PointModelX - (Map->Xorig + 0.5 * Map->DX)) / Map->DX); } else { Options->PointY = 0; Options->PointX = 0; } /**************** Determine model period ****************/ if (!CopyFloat(&(TimeStep), StrEnv[time_step].VarStr, 1)) ReportError(StrEnv[time_step].KeyName, 51); TimeStep *= SECPHOUR; if (!SScanDate(StrEnv[model_start].VarStr, &(Start))) ReportError(StrEnv[model_start].KeyName, 51); if (!SScanDate(StrEnv[model_end].VarStr, &(End))) ReportError(StrEnv[model_end].KeyName, 51); InitTime(Time, &Start, &End, NULL, NULL, (int) TimeStep); /**************** Determine model constants ****************/ if (!CopyFloat(&Z0_GROUND, StrEnv[ground_roughness].VarStr, 1)) ReportError(StrEnv[ground_roughness].KeyName, 51); if (!CopyFloat(&Z0_SNOW, StrEnv[snow_roughness].VarStr, 1)) ReportError(StrEnv[snow_roughness].KeyName, 51); if (!CopyFloat(&MIN_RAIN_TEMP, StrEnv[rain_threshold].VarStr, 1)) ReportError(StrEnv[rain_threshold].KeyName, 51); if (!CopyFloat(&MAX_SNOW_TEMP, StrEnv[snow_threshold].VarStr, 1)) ReportError(StrEnv[snow_threshold].KeyName, 51); if (!CopyFloat(&LIQUID_WATER_CAPACITY, StrEnv[snow_water_capacity].VarStr, 1)) ReportError(StrEnv[snow_water_capacity].KeyName, 51); if (!CopyFloat(&Zref, StrEnv[reference_height].VarStr, 1)) ReportError(StrEnv[reference_height].KeyName, 51); if (!CopyFloat(&LAI_WATER_MULTIPLIER, StrEnv[rain_lai_multiplier].VarStr, 1)) ReportError(StrEnv[rain_lai_multiplier].KeyName, 51); if (!CopyFloat(&LAI_SNOW_MULTIPLIER, StrEnv[snow_lai_multiplier].VarStr, 1)) ReportError(StrEnv[snow_lai_multiplier].KeyName, 51); if (!CopyFloat(&MIN_INTERCEPTION_STORAGE, StrEnv[min_intercepted_snow].VarStr, 1)) ReportError(StrEnv[min_intercepted_snow].KeyName, 51); if (!CopyUChar(&OUTSIDEBASIN, StrEnv[outside_basin].VarStr, 1)) ReportError(StrEnv[outside_basin].KeyName, 51); /* Glacier model terms MWW-glacier */ if(Options->GlacierMove == TRUE ) { if (!CopyFloat(&GLACIER_Q, StrEnv[glacier_creep_q].VarStr, 1)) ReportError(StrEnv[glacier_creep_q].KeyName, 51); if (!CopyFloat(&GLACIER_N, StrEnv[glacier_creep_n].VarStr, 1)) ReportError(StrEnv[glacier_creep_n].KeyName, 51); if (!CopyFloat(&MAX_GLACIER_FLUX, StrEnv[max_glacier_flux].VarStr, 1)) ReportError(StrEnv[max_glacier_flux].KeyName, 51); } if (Options->TempLapse == CONSTANT) { if (!CopyFloat(&TEMPLAPSE, StrEnv[temp_lapse_rate].VarStr, 1)) ReportError(StrEnv[temp_lapse_rate].KeyName, 51); } else if (Options->TempLapse == MONTHLY) { if (!CopyFloat( Basinwide->TempLapse, StrEnv[temp_lapse_rate].VarStr, 12)) ReportError(StrEnv[temp_lapse_rate].KeyName, 51); } else TEMPLAPSE = NOT_APPLICABLE; if (Options->PrecipLapse == CONSTANT) { if (!CopyFloat(&PRECIPLAPSE, StrEnv[precip_lapse_rate].VarStr, 1)) ReportError(StrEnv[precip_lapse_rate].KeyName, 51); } else if (Options->PrecipLapse == MONTHLY) { if (!CopyFloat( Basinwide->PrcpLapse, StrEnv[precip_lapse_rate].VarStr, 12)) ReportError(StrEnv[precip_lapse_rate].KeyName, 51); } else PRECIPLAPSE = NOT_APPLICABLE; if (Options->StreamTemp == TRUE) { if (!CopyFloat(&DEPTHRATIO, StrEnv[depthratio].VarStr, 1)) ReportError(StrEnv[depthratio].KeyName, 51); if (!CopyFloat(&ST_WIND_FAC, StrEnv[st_wind_fac].VarStr, 1)) ReportError(StrEnv[st_wind_fac].KeyName, 51); if (!CopyFloat(&ST_RAD_FAC, StrEnv[st_rad_fac].VarStr, 1)) ReportError(StrEnv[st_rad_fac].KeyName, 51); if (!CopyInt(&MIN_SEG_ORDER, StrEnv[min_seg_order].VarStr, 1)) ReportError(StrEnv[min_seg_order].KeyName, 51); } else { DEPTHRATIO = 1.0; ST_WIND_FAC = 1.0; ST_RAD_FAC = 1.0; MIN_SEG_ORDER = NOT_APPLICABLE; } /* This section added for Soil Chemistry functions, MWW -sc */ if (Options->Chemistry == TRUE) { if (!CopyFloat(&META_DOC_K_DECOMP, StrEnv[meta_doc_decomp_rate].VarStr, 1)) ReportError(StrEnv[meta_doc_decomp_rate].KeyName, 51); if (!CopyFloat(&STRUCT_DOC_K_DECOMP, StrEnv[struct_doc_decomp_rate].VarStr, 1)) ReportError(StrEnv[struct_doc_decomp_rate].KeyName, 51); if (!CopyFloat(&K_DECOMPOSE_DOC, StrEnv[k_decompose_doc].VarStr, 1)) ReportError(StrEnv[k_decompose_doc].KeyName, 51); if (!CopyFloat(&K1_SORPTION_MAX, StrEnv[k1_sorption_max].VarStr, 1)) ReportError(StrEnv[k1_sorption_max].KeyName, 51); if (!CopyFloat(&CN_SORB_DOM, StrEnv[cn_sorb_dom].VarStr, 1)) ReportError(StrEnv[cn_sorb_dom].KeyName, 51); if (!CopyFloat(&CN_MICRODECOMP_DOM, StrEnv[cn_microdecomp_dom].VarStr, 1)) ReportError(StrEnv[cn_microdecomp_dom].KeyName, 51); if (!CopyFloat(&BG_CATIONS, StrEnv[bg_cations].VarStr, 1)) ReportError(StrEnv[bg_cations].KeyName, 51); if (!CopyFloat(&NITRI_TEMP_FAC, StrEnv[nitri_temp_fac].VarStr, 1)) ReportError(StrEnv[nitri_temp_fac].KeyName, 51); if (!CopyFloat(&FREEAIRDCO2, StrEnv[freeair_co2].VarStr, 1)) ReportError(StrEnv[freeair_co2].KeyName, 51); if (!CopyFloat(&FREEAIROXY, StrEnv[freeair_co2].VarStr, 1)) ReportError(StrEnv[freeair_oxy].KeyName, 51); if (!CopyFloat(&CO2KGASTRANS, StrEnv[co2_kgas].VarStr, 1)) ReportError(StrEnv[co2_kgas].KeyName, 51); if (!CopyFloat(&O2KGASTRANS, StrEnv[o2_kgas].VarStr, 1)) ReportError(StrEnv[o2_kgas].KeyName, 51); if (!CopyFloat(&POTENTIALDENITRIF, StrEnv[pot_denitrif].VarStr, 1)) ReportError(StrEnv[pot_denitrif].KeyName, 51); if (!CopyFloat(&DENITRIF_HALFSAT, StrEnv[denitrif_halfsat].VarStr, 1)) ReportError(StrEnv[denitrif_halfsat].KeyName, 51); if (!CopyFloat(&KOXY_NITRIF, StrEnv[koxy_nitrif].VarStr, 1)) ReportError(StrEnv[koxy_nitrif].KeyName, 51); if (!CopyFloat(&KMINER_CHAN, StrEnv[kminer_chan].VarStr, 1)) ReportError(StrEnv[kminer_chan].KeyName, 51); if (!CopyFloat(&KHYDRO_CHAN, StrEnv[khydro_chan].VarStr, 1)) ReportError(StrEnv[khydro_chan].KeyName, 51); if (!CopyFloat(&KNITRIF1_CHAN, StrEnv[knitrif1_chan].VarStr, 1)) ReportError(StrEnv[knitrif1_chan].KeyName, 51); if (!CopyFloat(&KNITRIF2_CHAN, StrEnv[knitrif2_chan].VarStr, 1)) ReportError(StrEnv[knitrif2_chan].KeyName, 51); if (!CopyFloat( Basinwide->atmos_CO2_conc, StrEnv[atmos_co2_conc].VarStr, 12)) ReportError(StrEnv[atmos_co2_conc].KeyName, 51); if (!CopyFloat( Basinwide->atmos_DOC_conc, StrEnv[atmos_doc_conc].VarStr, 12)) ReportError(StrEnv[atmos_doc_conc].KeyName, 51); if (!CopyFloat( Basinwide->atmos_DON_conc, StrEnv[atmos_don_conc].VarStr, 12)) ReportError(StrEnv[atmos_don_conc].KeyName, 51); if (!CopyFloat( Basinwide->atmos_NH4_conc, StrEnv[atmos_nh4_conc].VarStr, 12)) ReportError(StrEnv[atmos_nh4_conc].KeyName, 51); if (!CopyFloat( Basinwide->atmos_NO3_conc, StrEnv[atmos_no3_conc].VarStr, 12)) ReportError(StrEnv[atmos_no3_conc].KeyName, 51); if (!CopyFloat( Basinwide->atmos_NO2_conc, StrEnv[atmos_no2_conc].VarStr, 12)) ReportError(StrEnv[atmos_no2_conc].KeyName, 51); } else { META_DOC_K_DECOMP = 0.0; STRUCT_DOC_K_DECOMP = 0.0; K_DECOMPOSE_DOC = 0.0; K1_SORPTION_MAX = 0.0; CN_SORB_DOM = 0.0; CN_MICRODECOMP_DOM = 0.0; FREEAIRDCO2 = 0.0; CO2KGASTRANS = 0.0; O2KGASTRANS = 0.0; POTENTIALDENITRIF = 0.0; DENITRIF_HALFSAT = 0.0; BG_CATIONS = 0.0; KOXY_NITRIF = 0.0; KMINER_CHAN = 0.0; KNITRIF1_CHAN = 0.0; KNITRIF2_CHAN = 0.0; for ( j=0;j<12;j++) { Basinwide->atmos_CO2_conc[j] = 0.0; Basinwide->atmos_DOC_conc[j] = 0.0; Basinwide->atmos_DON_conc[j] = 0.0; Basinwide->atmos_NH4_conc[j] = 0.0; Basinwide->atmos_NO3_conc[j] = 0.0; //Basinwide->atmos_NO3_conc[j] = 0.0; } } }
/***************************************************************************** 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 : *****************************************************************************/ void InitConstants(LISTPTR Input, OPTIONSTRUCT * Options, MAPSIZE * Map, SOLARGEOMETRY * SolarGeo, TIMESTRUCT * Time) { int i; /* counter */ double PointModelX; /* X-coordinate for POINT model mode */ double PointModelY; /* Y-coordinate for POINT model mode */ float TimeStep; /* Timestep in hours */ DATE End; /* End of run */ DATE Start; /* Start of run */ STRINIENTRY StrEnv[] = { {"OPTIONS", "FORMAT", "", ""}, {"OPTIONS", "EXTENT", "", ""}, {"OPTIONS", "GRADIENT", "", ""}, {"OPTIONS", "FLOW ROUTING", "", ""}, {"OPTIONS", "SENSIBLE HEAT FLUX", "", ""}, {"OPTIONS", "SEDIMENT", "", ""}, {"OPTIONS", "SEDIMENT INPUT FILE", "", ""}, {"OPTIONS", "OVERLAND ROUTING", "", ""}, {"OPTIONS", "INFILTRATION", "", ""}, {"OPTIONS", "INTERPOLATION", "", ""}, {"OPTIONS", "MM5", "", ""}, {"OPTIONS", "QPF", "", ""}, {"OPTIONS", "PRISM", "", ""}, {"OPTIONS", "CANOPY RADIATION ATTENUATION MODE", "", ""}, {"OPTIONS", "SHADING", "", ""}, {"OPTIONS", "SNOTEL", "", ""}, {"OPTIONS", "OUTSIDE", "", ""}, {"OPTIONS", "RHOVERRIDE", "", ""}, {"OPTIONS", "PRECIPITATION SOURCE", "", ""}, {"OPTIONS", "WIND SOURCE", "", ""}, {"OPTIONS", "TEMPERATURE LAPSE RATE", "", ""}, {"OPTIONS", "PRECIPITATION LAPSE RATE", "", ""}, {"OPTIONS", "CRESSMAN RADIUS", "", ""}, {"OPTIONS", "CRESSMAN STATIONS", "", ""}, {"OPTIONS", "PRISM DATA PATH", "", ""}, {"OPTIONS", "PRISM DATA EXTENSION", "", ""}, {"OPTIONS", "SHADING DATA PATH", "", ""}, {"OPTIONS", "SHADING DATA EXTENSION", "", ""}, {"OPTIONS", "SKYVIEW DATA PATH", "", ""}, {"OPTIONS", "STREAM TEMPERATURE", "", ""}, {"OPTIONS", "CANOPY SHADING", "", ""}, {"AREA", "COORDINATE SYSTEM", "", ""}, {"AREA", "EXTREME NORTH", "", ""}, {"AREA", "EXTREME WEST", "", ""}, {"AREA", "CENTER LATITUDE", "", ""}, {"AREA", "CENTER LONGITUDE", "", ""}, {"AREA", "TIME ZONE MERIDIAN", "", ""}, {"AREA", "NUMBER OF ROWS", "", ""}, {"AREA", "NUMBER OF COLUMNS", "", ""}, {"AREA", "GRID SPACING", "", ""}, {"AREA", "POINT NORTH", "", ""}, {"AREA", "POINT EAST", "", ""}, {"TIME", "TIME STEP", "", ""}, {"TIME", "MODEL START", "", ""}, {"TIME", "MODEL END", "", ""}, {"CONSTANTS", "GROUND ROUGHNESS", "", ""}, {"CONSTANTS", "SNOW ROUGHNESS", "", ""}, {"CONSTANTS", "RAIN THRESHOLD", "", ""}, {"CONSTANTS", "SNOW THRESHOLD", "", ""}, {"CONSTANTS", "SNOW WATER CAPACITY", "", ""}, {"CONSTANTS", "REFERENCE HEIGHT", "", ""}, {"CONSTANTS", "RAIN LAI MULTIPLIER", "", ""}, {"CONSTANTS", "SNOW LAI MULTIPLIER", "", ""}, {"CONSTANTS", "MIN INTERCEPTED SNOW", "", ""}, {"CONSTANTS", "OUTSIDE BASIN VALUE", "", ""}, {"CONSTANTS", "TEMPERATURE LAPSE RATE", "", ""}, {"CONSTANTS", "PRECIPITATION LAPSE RATE", "", ""}, {"CONSTANTS", "PRECIPITATION MULTIPLIER", "", ""}, {NULL, NULL, "", NULL} }; /* Read the key-entry pairs from the input file */ for (i = 0; StrEnv[i].SectionName; i++) GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default, StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input); /**************** Determine model options ****************/ /* Determine file format to be used */ if (strncmp(StrEnv[format].VarStr, "BIN", 3) == 0) Options->FileFormat = BIN; else if (strncmp(StrEnv[format].VarStr, "NETCDF", 3) == 0) Options->FileFormat = NETCDF; else if (strncmp(StrEnv[format].VarStr, "BYTESWAP", 3) == 0) Options->FileFormat = BYTESWAP; else ReportError(StrEnv[format].KeyName, 51); /* Determine whether the model should be run in POINT mode or in BASIN mode. If in POINT mode also read which pixel to model */ if (strncmp(StrEnv[extent].VarStr, "POINT", 5) == 0) { Options->Extent = POINT; Options->HasNetwork = FALSE; } else if (strncmp(StrEnv[extent].VarStr, "BASIN", 5) == 0) { Options->Extent = BASIN; } else ReportError(StrEnv[extent].KeyName, 51); /* Determine how the flow gradient should be calculated */ if (Options->Extent != POINT) { if (strncmp(StrEnv[gradient].VarStr, "TOPO", 4) == 0) Options->FlowGradient = TOPOGRAPHY; else if (strncmp(StrEnv[gradient].VarStr, "WATER", 5) == 0) Options->FlowGradient = WATERTABLE; else ReportError(StrEnv[gradient].KeyName, 51); } else Options->FlowGradient = NOT_APPLICABLE; /* Determine what meterological interpolation to use */ if (strncmp(StrEnv[interpolation].VarStr, "INVDIST", 7) == 0) Options->Interpolation = INVDIST; else if (strncmp(StrEnv[interpolation].VarStr, "NEAREST", 7) == 0) Options->Interpolation = NEAREST; else if (strncmp(StrEnv[interpolation].VarStr, "VARCRESS", 8) == 0) Options->Interpolation = VARCRESS; else ReportError(StrEnv[interpolation].KeyName, 51); /* if VARIABLE CRESTMAN interpolation then get parameters */ if (Options->Interpolation == VARCRESS) { if (!CopyInt(&(Options->CressRadius), StrEnv[cressman_radius].VarStr, 1)) ReportError(StrEnv[cressman_radius].KeyName, 51); if (!CopyInt (&(Options->CressStations), StrEnv[cressman_stations].VarStr, 1)) ReportError(StrEnv[cressman_stations].KeyName, 51); } /* Determine whether a road/network is imposed on the model area */ if (Options->Extent != POINT) { if (strncmp(StrEnv[flow_routing].VarStr, "NETWORK", 7) == 0) Options->HasNetwork = TRUE; else if (strncmp(StrEnv[flow_routing].VarStr, "UNIT", 4) == 0) Options->HasNetwork = FALSE; else ReportError(StrEnv[flow_routing].KeyName, 51); } else Options->HasNetwork = FALSE; /* Determine whether a sensible heat flux should be calculated */ if (strncmp(StrEnv[sensible_heat_flux].VarStr, "TRUE", 4) == 0) Options->HeatFlux = TRUE; else if (strncmp(StrEnv[sensible_heat_flux].VarStr, "FALSE", 5) == 0) Options->HeatFlux = FALSE; else ReportError(StrEnv[sensible_heat_flux].KeyName, 51); /* Determine whether sediment model should be run */ if (strncmp(StrEnv[sediment].VarStr, "TRUE", 4) == 0) Options->Sediment = TRUE; else if (strncmp(StrEnv[sediment].VarStr, "FALSE", 5) == 0){ printf("WARNING: Sediment option has not been chosen. All erosion\n"); printf("options are being turned off.\n\n"); Options->Sediment = FALSE; Options->MassWaste = FALSE; Options->SurfaceErosion = FALSE; Options->ErosionPeriod = FALSE; } else ReportError(StrEnv[sediment].KeyName, 51); if(Options->Sediment == TRUE) { if (IsEmptyStr(StrEnv[sed_input_file].VarStr)) ReportError(StrEnv[sed_input_file].KeyName, 51); strcpy(Options->SedFile, StrEnv[sed_input_file].VarStr); } /* Determine overland flow routing method to use */ if (strncmp(StrEnv[routing].VarStr, "KINEMATIC", 9) == 0) Options->Routing = TRUE; else if (strncmp(StrEnv[routing].VarStr, "CONVENTIONAL", 12) == 0) Options->Routing = FALSE; else ReportError(StrEnv[routing].KeyName, 51); /* Determine if the maximum infiltration rate is static or dynamic */ if (strncmp(StrEnv[infiltration].VarStr, "STATIC", 6) == 0) { Options->Infiltration = STATIC; } else if (strncmp(StrEnv[infiltration].VarStr, "DYNAMIC", 7) == 0) { Options->Infiltration = DYNAMIC ; printf("WARNING: Dynamic maximum infiltration capacity has\n"); printf("not been fully tested. It is a work in progress.\n\n"); } else ReportError(StrEnv[infiltration].KeyName, 51); /* Determine whether the mm5 interface should be used */ if (strncmp(StrEnv[mm5].VarStr, "TRUE", 4) == 0) Options->MM5 = TRUE; else if (strncmp(StrEnv[mm5].VarStr, "FALSE", 5) == 0) Options->MM5 = FALSE; else ReportError(StrEnv[mm5].KeyName, 51); /* Determine whether the QPF override should be used on the MM5 fields */ if (strncmp(StrEnv[qpf].VarStr, "TRUE", 4) == 0) Options->QPF = TRUE; else if (strncmp(StrEnv[qpf].VarStr, "FALSE", 5) == 0) Options->QPF = FALSE; else ReportError(StrEnv[qpf].KeyName, 51); /* Determine if PRISM maps will be used to interpolate precip fields */ if (strncmp(StrEnv[prism].VarStr, "TRUE", 4) == 0) Options->Prism = TRUE; else if (strncmp(StrEnv[prism].VarStr, "FALSE", 5) == 0) Options->Prism = FALSE; else ReportError(StrEnv[prism].KeyName, 51); /* Determine the kind of canopy radiation attenuation to be used */ if (strncmp(StrEnv[canopy_radatt].VarStr, "FIXED", 3) == 0) Options->CanopyRadAtt = FIXED; else if (strncmp(StrEnv[canopy_radatt].VarStr, "VARIABLE", 3) == 0) Options->CanopyRadAtt = VARIABLE; else ReportError(StrEnv[canopy_radatt].KeyName, 51); /* Determine if solar shading maps will be used */ if (strncmp(StrEnv[shading].VarStr, "TRUE", 4) == 0) Options->Shading = TRUE; else if (strncmp(StrEnv[shading].VarStr, "FALSE", 5) == 0) Options->Shading = FALSE; else ReportError(StrEnv[shading].KeyName, 51); if (Options->MM5 == TRUE && Options->Prism == TRUE && Options->QPF == FALSE) ReportError(StrEnv[prism].KeyName, 51); /* Determine if Snotel test is called for */ if (strncmp(StrEnv[snotel].VarStr, "TRUE", 4) == 0) Options->Snotel = TRUE; else if (strncmp(StrEnv[snotel].VarStr, "FALSE", 5) == 0) Options->Snotel = FALSE; else ReportError(StrEnv[snotel].KeyName, 51); /* Determine if STREAM TEMP is called for */ if (strncmp(StrEnv[stream_temp].VarStr, "TRUE", 4) == 0) Options->StreamTemp = TRUE; else if (strncmp(StrEnv[stream_temp].VarStr, "FALSE", 5) == 0) Options->StreamTemp = FALSE; else ReportError(StrEnv[stream_temp].KeyName, 51); /* Determine if CANOPY SHADING is called for */ if (strncmp(StrEnv[canopy_shading].VarStr, "TRUE", 4) == 0) { Options->CanopyShading = TRUE; if (Options->StreamTemp == FALSE) { printf("Stream temp module must be turned on to allow canopy shading options\n"); exit(-1); } } else if (strncmp(StrEnv[canopy_shading].VarStr, "FALSE", 5) == 0) Options->CanopyShading = FALSE; else ReportError(StrEnv[canopy_shading].KeyName, 51); /* Determine if listed met stations outside bounding box are used */ if (strncmp(StrEnv[outside].VarStr, "TRUE", 4) == 0) Options->Outside = TRUE; else if (strncmp(StrEnv[outside].VarStr, "FALSE", 5) == 0) Options->Outside = FALSE; else ReportError(StrEnv[outside].KeyName, 51); if (Options->Prism == TRUE) { if (IsEmptyStr(StrEnv[prism_data_path].VarStr)) ReportError(StrEnv[prism_data_path].KeyName, 51); strcpy(Options->PrismDataPath, StrEnv[prism_data_path].VarStr); if (IsEmptyStr(StrEnv[prism_data_ext].VarStr)) ReportError(StrEnv[prism_data_ext].KeyName, 51); strcpy(Options->PrismDataExt, StrEnv[prism_data_ext].VarStr); } if (Options->Shading == TRUE) { if (IsEmptyStr(StrEnv[shading_data_path].VarStr)) ReportError(StrEnv[shading_data_path].KeyName, 51); strcpy(Options->ShadingDataPath, StrEnv[shading_data_path].VarStr); if (IsEmptyStr(StrEnv[shading_data_ext].VarStr)) ReportError(StrEnv[shading_data_ext].KeyName, 51); strcpy(Options->ShadingDataExt, StrEnv[shading_data_ext].VarStr); if (IsEmptyStr(StrEnv[skyview_data_path].VarStr)) ReportError(StrEnv[skyview_data_path].KeyName, 51); strcpy(Options->SkyViewDataPath, StrEnv[skyview_data_path].VarStr); } /* Determine if rh override is used */ if (strncmp(StrEnv[rhoverride].VarStr, "TRUE", 4) == 0) Options->Rhoverride = TRUE; else if (strncmp(StrEnv[rhoverride].VarStr, "FALSE", 5) == 0) Options->Rhoverride = FALSE; else ReportError(StrEnv[rhoverride].KeyName, 51); /* The other met options are only of importance if MM5 is FALSE */ if (Options->MM5 == TRUE) { Options->PrecipType = NOT_APPLICABLE; Options->WindSource = NOT_APPLICABLE; Options->PrecipLapse = NOT_APPLICABLE; Options->TempLapse = NOT_APPLICABLE; if (Options->QPF == TRUE) Options->PrecipType = STATION; if (Options->QPF == TRUE && Options->Prism == FALSE) Options->PrecipLapse = CONSTANT; } else { /* Determine the type of precipitation data that the model will use */ if (strncmp(StrEnv[precipitation_source].VarStr, "RADAR", 5) == 0) Options->PrecipType = RADAR; else if (strncmp(StrEnv[precipitation_source].VarStr, "STATION", 7) == 0) Options->PrecipType = STATION; else ReportError(StrEnv[precipitation_source].KeyName, 51); /* Determine the type of wind data that the model will use */ if (strncmp(StrEnv[wind_source].VarStr, "MODEL", 5) == 0) Options->WindSource = MODEL; else if (strncmp(StrEnv[wind_source].VarStr, "STATION", 7) == 0) Options->WindSource = STATION; else ReportError(StrEnv[wind_source].KeyName, 51); /* Determine the type of temperature lapse rate */ if (strncmp(StrEnv[temp_lapse].VarStr, "CONSTANT", 8) == 0) Options->TempLapse = CONSTANT; else if (strncmp(StrEnv[temp_lapse].VarStr, "VARIABLE", 8) == 0) Options->TempLapse = VARIABLE; else ReportError(StrEnv[temp_lapse].KeyName, 51); /* Determine the type of precipitation lapse rate */ if (strncmp(StrEnv[precip_lapse].VarStr, "CONSTANT", 8) == 0) Options->PrecipLapse = CONSTANT; else if (strncmp(StrEnv[precip_lapse].VarStr, "MAP", 3) == 0) Options->PrecipLapse = MAP; else if (strncmp(StrEnv[precip_lapse].VarStr, "VARIABLE", 8) == 0) Options->PrecipLapse = VARIABLE; else ReportError(StrEnv[precip_lapse].KeyName, 51); } /**************** Determine areal extent ****************/ if (IsEmptyStr(StrEnv[coordinate_system].VarStr)) ReportError(StrEnv[coordinate_system].KeyName, 51); strcpy(Map->System, StrEnv[coordinate_system].VarStr); if (!CopyDouble(&(Map->Yorig), StrEnv[extreme_north].VarStr, 1)) ReportError(StrEnv[extreme_north].KeyName, 51); if (!CopyDouble(&(Map->Xorig), StrEnv[extreme_west].VarStr, 1)) ReportError(StrEnv[extreme_west].KeyName, 51); if (!CopyFloat(&(SolarGeo->Latitude), StrEnv[center_latitude].VarStr, 1)) ReportError(StrEnv[center_latitude].KeyName, 51); SolarGeo->Latitude *= (float) RADPDEG; if (!CopyFloat(&(SolarGeo->Longitude), StrEnv[center_longitude].VarStr, 1)) ReportError(StrEnv[center_longitude].KeyName, 51); SolarGeo->Longitude *= (float) RADPDEG; if (!CopyFloat(&(SolarGeo->StandardMeridian), StrEnv[time_zone_meridian].VarStr, 1)) ReportError(StrEnv[time_zone_meridian].KeyName, 51); SolarGeo->StandardMeridian *= (float) RADPDEG; if (!CopyInt(&(Map->NY), StrEnv[number_of_rows].VarStr, 1)) ReportError(StrEnv[number_of_rows].KeyName, 51); if (!CopyInt(&(Map->NX), StrEnv[number_of_columns].VarStr, 1)) ReportError(StrEnv[number_of_columns].KeyName, 51); if (!CopyFloat(&(Map->DY), StrEnv[grid_spacing].VarStr, 1)) ReportError(StrEnv[grid_spacing].KeyName, 51); Map->DX = Map->DY; Map->DXY = (float) sqrt(Map->DX * Map->DX + Map->DY * Map->DY); Map->X = 0; Map->Y = 0; Map->OffsetX = 0; Map->OffsetY = 0; Map->NumCells = 0; if (Options->Extent == POINT) { if (!CopyDouble(&PointModelY, StrEnv[point_north].VarStr, 1)) ReportError(StrEnv[point_north].KeyName, 51); if (!CopyDouble(&PointModelX, StrEnv[point_east].VarStr, 1)) ReportError(StrEnv[point_east].KeyName, 51); Options->PointY = Round(((Map->Yorig - 0.5 * Map->DY) - PointModelY) / Map->DY); Options->PointX = Round((PointModelX - (Map->Xorig + 0.5 * Map->DX)) / Map->DX); } else { Options->PointY = 0; Options->PointX = 0; } /**************** Determine model period ****************/ if (!CopyFloat(&(TimeStep), StrEnv[time_step].VarStr, 1)) ReportError(StrEnv[time_step].KeyName, 51); TimeStep *= SECPHOUR; if (!SScanDate(StrEnv[model_start].VarStr, &(Start))) ReportError(StrEnv[model_start].KeyName, 51); if (!SScanDate(StrEnv[model_end].VarStr, &(End))) ReportError(StrEnv[model_end].KeyName, 51); InitTime(Time, &Start, &End, NULL, NULL, (int) TimeStep); /**************** Determine model constants ****************/ if (!CopyFloat(&Z0_GROUND, StrEnv[ground_roughness].VarStr, 1)) ReportError(StrEnv[ground_roughness].KeyName, 51); if (!CopyFloat(&Z0_SNOW, StrEnv[snow_roughness].VarStr, 1)) ReportError(StrEnv[snow_roughness].KeyName, 51); if (!CopyFloat(&MIN_RAIN_TEMP, StrEnv[rain_threshold].VarStr, 1)) ReportError(StrEnv[rain_threshold].KeyName, 51); if (!CopyFloat(&MAX_SNOW_TEMP, StrEnv[snow_threshold].VarStr, 1)) ReportError(StrEnv[snow_threshold].KeyName, 51); if (!CopyFloat(&LIQUID_WATER_CAPACITY, StrEnv[snow_water_capacity].VarStr, 1)) ReportError(StrEnv[snow_water_capacity].KeyName, 51); if (!CopyFloat(&Zref, StrEnv[reference_height].VarStr, 1)) ReportError(StrEnv[reference_height].KeyName, 51); if (!CopyFloat(&LAI_WATER_MULTIPLIER, StrEnv[rain_lai_multiplier].VarStr, 1)) ReportError(StrEnv[rain_lai_multiplier].KeyName, 51); if (!CopyFloat(&LAI_SNOW_MULTIPLIER, StrEnv[snow_lai_multiplier].VarStr, 1)) ReportError(StrEnv[snow_lai_multiplier].KeyName, 51); if (!CopyFloat(&MIN_INTERCEPTION_STORAGE, StrEnv[min_intercepted_snow].VarStr, 1)) ReportError(StrEnv[min_intercepted_snow].KeyName, 51); if (!CopyUChar(&OUTSIDEBASIN, StrEnv[outside_basin].VarStr, 1)) ReportError(StrEnv[outside_basin].KeyName, 51); if (Options->TempLapse == CONSTANT) { if (!CopyFloat(&TEMPLAPSE, StrEnv[temp_lapse_rate].VarStr, 1)) ReportError(StrEnv[temp_lapse_rate].KeyName, 51); } else TEMPLAPSE = NOT_APPLICABLE; if (Options->PrecipLapse == CONSTANT) { if (!CopyFloat(&PRECIPLAPSE, StrEnv[precip_lapse_rate].VarStr, 1)) ReportError(StrEnv[precip_lapse_rate].KeyName, 51); } else PRECIPLAPSE = NOT_APPLICABLE; if (!CopyFloat(&PRECIPMULTIPLIER, StrEnv[precip_multiplier].VarStr, 1)) ReportError(StrEnv[precip_multiplier].KeyName, 51); }