void readRouting() // // Input: none // Output: none // Purpose: reads initial state of all nodes, links and groundwater objects // from hotstart file. // { int i, j; float x; double xgw[4]; FILE* f = Fhotstart1.file; // --- for file format 2, assign GW moisture content and lower depth if ( fileVersion == 2 ) { // --- flow and available upper zone volume not used xgw[2] = 0.0; xgw[3] = MISSING; for (i = 0; i < Nobjects[SUBCATCH]; i++) { // --- read moisture content and water table elevation as floats if ( !readFloat(&x, f) ) return; xgw[0] = x; if ( !readFloat(&x, f) ) return; xgw[1] = x; // --- set GW state if ( Subcatch[i].groundwater != NULL ) gwater_setState(i, xgw); } } // --- read node states for (i = 0; i < Nobjects[NODE]; i++) { if ( !readFloat(&x, f) ) return; Node[i].newDepth = x; if ( !readFloat(&x, f) ) return; Node[i].newLatFlow = x; if ( fileVersion >= 4 && Node[i].type == STORAGE ) { if ( !readFloat(&x, f) ) return; j = Node[i].subIndex; Storage[j].hrt = x; } for (j = 0; j < Nobjects[POLLUT]; j++) { if ( !readFloat(&x, f) ) return; Node[i].newQual[j] = x; } // --- read in zeros here for backwards compatibility if ( fileVersion <= 2 ) { for (j = 0; j < Nobjects[POLLUT]; j++) { if ( !readFloat(&x, f) ) return; } } } // --- read link states for (i = 0; i < Nobjects[LINK]; i++) { if ( !readFloat(&x, f) ) return; Link[i].newFlow = x; if ( !readFloat(&x, f) ) return; Link[i].newDepth = x; if ( !readFloat(&x, f) ) return; Link[i].setting = x; // --- set link's target setting to saved setting Link[i].targetSetting = x; link_setTargetSetting(i); link_setSetting(i, 0.0); for (j = 0; j < Nobjects[POLLUT]; j++) { if ( !readFloat(&x, f) ) return; Link[i].newQual[j] = x; } } }
void routing_execute(int routingModel, double routingStep) // // Input: routingModel = routing method code // routingStep = routing time step (sec) // Output: none // Purpose: executes the routing process at the current time period. // { int j; int stepCount = 1; int actionCount = 0; int inSteadyState = FALSE; DateTime currentDate; double stepFlowError; // --- update continuity with current state // applied over 1/2 of time step if ( ErrorCode ) return; massbal_updateRoutingTotals(routingStep/2.); // --- evaluate control rules at current date and elapsed time currentDate = getDateTime(NewRoutingTime); for (j=0; j<Nobjects[LINK]; j++) link_setTargetSetting(j); controls_evaluate(currentDate, currentDate - StartDateTime, routingStep/SECperDAY); for (j=0; j<Nobjects[LINK]; j++) { if ( Link[j].targetSetting != Link[j].setting ) { Link[j].timeLastSet = currentDate; //(5.1.010) link_setSetting(j, routingStep); actionCount++; } } // --- update value of elapsed routing time (in milliseconds) OldRoutingTime = NewRoutingTime; NewRoutingTime = NewRoutingTime + 1000.0 * routingStep; // currentDate = getDateTime(NewRoutingTime); //Deleted //(5.1.008) // --- initialize mass balance totals for time step stepFlowError = massbal_getStepFlowError(); massbal_initTimeStepTotals(); // --- replace old water quality state with new state if ( Nobjects[POLLUT] > 0 ) { for (j=0; j<Nobjects[NODE]; j++) node_setOldQualState(j); for (j=0; j<Nobjects[LINK]; j++) link_setOldQualState(j); } // --- add lateral inflows and evap/seepage losses at nodes //(5.1.007) for (j = 0; j < Nobjects[NODE]; j++) { Node[j].oldLatFlow = Node[j].newLatFlow; Node[j].newLatFlow = 0.0; Node[j].losses = node_getLosses(j, routingStep); //(5.1.007) } addExternalInflows(currentDate); addDryWeatherInflows(currentDate); addWetWeatherInflows(OldRoutingTime); //(5.1.008) addGroundwaterInflows(OldRoutingTime); //(5.1.008) addLidDrainInflows(OldRoutingTime); //(5.1.008) addRdiiInflows(currentDate); addIfaceInflows(currentDate); // --- check if can skip steady state periods if ( SkipSteadyState ) { if ( OldRoutingTime == 0.0 || actionCount > 0 || fabs(stepFlowError) > SysFlowTol || inflowHasChanged() ) inSteadyState = FALSE; else inSteadyState = TRUE; } // --- find new hydraulic state if system has changed if ( inSteadyState == FALSE ) { // --- replace old hydraulic state values with current ones for (j = 0; j < Nobjects[LINK]; j++) link_setOldHydState(j); for (j = 0; j < Nobjects[NODE]; j++) { node_setOldHydState(j); node_initInflow(j, routingStep); } // --- route flow through the drainage network if ( Nobjects[LINK] > 0 ) { stepCount = flowrout_execute(SortedLinks, routingModel, routingStep); } } // --- route quality through the drainage network if ( Nobjects[POLLUT] > 0 && !IgnoreQuality ) { qualrout_execute(routingStep); } // --- remove evaporation, infiltration & outflows from system removeStorageLosses(routingStep); removeConduitLosses(); removeOutflows(routingStep); //(5.1.008) // --- update continuity with new totals // applied over 1/2 of routing step massbal_updateRoutingTotals(routingStep/2.); // --- update summary statistics if ( RptFlags.flowStats && Nobjects[LINK] > 0 ) { stats_updateFlowStats(routingStep, getDateTime(NewRoutingTime), //(5.1.008) stepCount, inSteadyState); } }
void routing_execute(int routingModel, double routingStep) // // Input: routingModel = routing method code // routingStep = routing time step (sec) // Output: none // Purpose: executes the routing process at the current time period. // { int j; int stepCount = 1; int actionCount = 0; //(5.0.010 - LR) DateTime currentDate; double stepFlowError; //(5.0.012 - LR) // --- update continuity with current state // applied over 1/2 of time step if ( ErrorCode ) return; massbal_updateRoutingTotals(routingStep/2.); // --- evaluate control rules at current date and elapsed time currentDate = getDateTime(NewRoutingTime); for (j=0; j<Nobjects[LINK]; j++) link_setTargetSetting(j); //(5.0.010 - LR) controls_evaluate(currentDate, currentDate - StartDateTime, //(5.0.010 - LR) routingStep/SECperDAY); //(5.0.010 - LR) for (j=0; j<Nobjects[LINK]; j++) //(5.0.010 - LR) { //(5.0.010 - LR) if ( Link[j].targetSetting != Link[j].setting ) //(5.0.010 - LR) { //(5.0.010 - LR) link_setSetting(j, routingStep); //(5.0.010 - LR) actionCount++; //(5.0.010 - LR) } //(5.0.010 - LR) } //(5.0.010 - LR) // --- update value of elapsed routing time (in milliseconds) OldRoutingTime = NewRoutingTime; NewRoutingTime = NewRoutingTime + 1000.0 * routingStep; currentDate = getDateTime(NewRoutingTime); // --- initialize mass balance totals for time step stepFlowError = massbal_getStepFlowError(); //(5.0.012 - LR) massbal_initTimeStepTotals(); // --- replace old water quality state with new state if ( Nobjects[POLLUT] > 0 ) { for (j=0; j<Nobjects[NODE]; j++) node_setOldQualState(j); for (j=0; j<Nobjects[LINK]; j++) link_setOldQualState(j); } // --- add lateral inflows to nodes for (j = 0; j < Nobjects[NODE]; j++) { Node[j].oldLatFlow = Node[j].newLatFlow; Node[j].newLatFlow = 0.0; } addExternalInflows(currentDate); addDryWeatherInflows(currentDate); addWetWeatherInflows(NewRoutingTime); addGroundwaterInflows(NewRoutingTime); addRdiiInflows(currentDate); addIfaceInflows(currentDate); // --- check if can skip steady state periods if ( SkipSteadyState ) { if ( OldRoutingTime == 0.0 || actionCount > 0 || fabs(stepFlowError) > FLOW_ERR_TOL //(5.0.012 - LR) || systemHasChanged(routingModel) ) InSteadyState = FALSE; else InSteadyState = TRUE; } // --- find new hydraulic state if system has changed if ( InSteadyState == FALSE ) { // --- replace old hydraulic state values with current ones for (j = 0; j < Nobjects[LINK]; j++) link_setOldHydState(j); for (j = 0; j < Nobjects[NODE]; j++) { node_setOldHydState(j); node_initInflow(j, routingStep); } // --- route flow through the drainage network if ( Nobjects[LINK] > 0 ) { stepCount = flowrout_execute(SortedLinks, routingModel, routingStep); } } // --- route quality through the drainage network if ( Nobjects[POLLUT] > 0 ) { qualrout_execute(routingStep); } // --- remove evaporation & system outflows from nodes findEvap(routingStep); removeOutflows(); // --- update continuity with new totals // applied over 1/2 of routing step massbal_updateRoutingTotals(routingStep/2.); // --- update summary statistics if ( RptFlags.flowStats && Nobjects[LINK] > 0 ) { stats_updateFlowStats(routingStep, currentDate, stepCount, InSteadyState); } }