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); } }
int massbal_open() // // Input: none // Output: returns error code // Purpose: opens and initializes mass balance continuity checking. // { int j, n; // --- initialize global continuity errors RunoffError = 0.0; GwaterError = 0.0; FlowError = 0.0; QualError = 0.0; // --- initialize runoff totals RunoffTotals.rainfall = 0.0; RunoffTotals.evap = 0.0; RunoffTotals.infil = 0.0; RunoffTotals.runoff = 0.0; RunoffTotals.snowRemoved = 0.0; RunoffTotals.initStorage = 0.0; RunoffTotals.initSnowCover = 0.0; TotalArea = 0.0; for (j = 0; j < Nobjects[SUBCATCH]; j++) { RunoffTotals.initSnowCover += snow_getSnowCover(j); TotalArea += Subcatch[j].area; } // --- initialize groundwater totals GwaterTotals.infil = 0.0; GwaterTotals.upperEvap = 0.0; GwaterTotals.lowerEvap = 0.0; GwaterTotals.lowerPerc = 0.0; GwaterTotals.gwater = 0.0; GwaterTotals.initStorage = 0.0; GwaterTotals.finalStorage = 0.0; for ( j = 0; j < Nobjects[SUBCATCH]; j++ ) { GwaterTotals.initStorage += gwater_getVolume(j) * Subcatch[j].area; } // --- initialize node flow & storage totals FlowTotals.dwInflow = 0.0; FlowTotals.wwInflow = 0.0; FlowTotals.gwInflow = 0.0; FlowTotals.iiInflow = 0.0; FlowTotals.exInflow = 0.0; FlowTotals.floodingNumNodes = 0.0; FlowTotals.outflow = 0.0; FlowTotals.pumpedVol = 0.0; FlowTotals.initStorage = 0.0; for (j = 0; j < Nobjects[NODE]; j++) FlowTotals.initStorage += Node[j].newVolume; for (j = 0; j < Nobjects[LINK]; j++) FlowTotals.initStorage += Link[j].newVolume; StepFlowTotals = FlowTotals; // --- initialize arrays to null LoadingTotals = NULL; QualTotals = NULL; StepQualTotals = NULL; NodeInflow = NULL; NodeOutflow = NULL; // --- allocate memory for WQ washoff continuity totals n = Nobjects[POLLUT]; if ( n > 0 ) { LoadingTotals = (TLoadingTotals *) calloc(n, sizeof(TLoadingTotals)); if ( LoadingTotals == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } for (j = 0; j < n; j++) { LoadingTotals[j].initLoad = massbal_getBuildup(j); LoadingTotals[j].buildup = 0.0; LoadingTotals[j].deposition = 0.0; LoadingTotals[j].sweeping = 0.0; LoadingTotals[j].infil = 0.0; LoadingTotals[j].bmpRemoval = 0.0; LoadingTotals[j].runoff = 0.0; LoadingTotals[j].finalLoad = 0.0; } } // --- allocate memory for nodal WQ continuity totals if ( n > 0 ) { QualTotals = (TRoutingTotals *) calloc(n, sizeof(TRoutingTotals)); StepQualTotals = (TRoutingTotals *) calloc(n, sizeof(TRoutingTotals)); if ( QualTotals == NULL || StepQualTotals == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } } // --- initialize WQ totals for (j = 0; j < n; j++) { QualTotals[j].dwInflow = 0.0; QualTotals[j].wwInflow = 0.0; QualTotals[j].gwInflow = 0.0; QualTotals[j].exInflow = 0.0; QualTotals[j].floodingNumNodes = 0.0; QualTotals[j].outflow = 0.0; QualTotals[j].pumpedVol = 0.0; QualTotals[j].initStorage = 0.0; } // --- initialize totals used over a single time step massbal_initTimeStepTotals(); // --- allocate memory for nodal flow continuity if ( Nobjects[NODE] > 0 ) { NodeInflow = (double *) calloc(Nobjects[NODE], sizeof(double)); if ( NodeInflow == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } NodeOutflow = (double *) calloc(Nobjects[NODE], sizeof(double)); if ( NodeOutflow == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } for (j = 0; j < Nobjects[NODE]; j++) NodeInflow[j] = Node[j].newVolume; } return ErrorCode; }
int massbal_open() // // Input: none // Output: returns error code // Purpose: opens and initializes mass balance continuity checking. // { int j, n; // --- initialize global continuity errors RunoffError = 0.0; GwaterError = 0.0; FlowError = 0.0; QualError = 0.0; // --- initialize runoff totals RunoffTotals.rainfall = 0.0; RunoffTotals.evap = 0.0; RunoffTotals.infil = 0.0; RunoffTotals.runoff = 0.0; RunoffTotals.runon = 0.0; //(5.1.008) RunoffTotals.drains = 0.0; //(5.1.008) RunoffTotals.snowRemoved = 0.0; RunoffTotals.initStorage = 0.0; RunoffTotals.initSnowCover = 0.0; TotalArea = 0.0; for (j = 0; j < Nobjects[SUBCATCH]; j++) { RunoffTotals.initStorage += subcatch_getStorage(j); RunoffTotals.initSnowCover += snow_getSnowCover(j); TotalArea += Subcatch[j].area; } // --- initialize groundwater totals GwaterTotals.infil = 0.0; GwaterTotals.upperEvap = 0.0; GwaterTotals.lowerEvap = 0.0; GwaterTotals.lowerPerc = 0.0; GwaterTotals.gwater = 0.0; GwaterTotals.initStorage = 0.0; GwaterTotals.finalStorage = 0.0; for ( j = 0; j < Nobjects[SUBCATCH]; j++ ) { GwaterTotals.initStorage += gwater_getVolume(j) * Subcatch[j].area; } // --- initialize node flow & storage totals FlowTotals.dwInflow = 0.0; FlowTotals.wwInflow = 0.0; FlowTotals.gwInflow = 0.0; FlowTotals.iiInflow = 0.0; FlowTotals.exInflow = 0.0; FlowTotals.flooding = 0.0; FlowTotals.outflow = 0.0; FlowTotals.evapLoss = 0.0; FlowTotals.seepLoss = 0.0; FlowTotals.reacted = 0.0; FlowTotals.initStorage = 0.0; for (j = 0; j < Nobjects[NODE]; j++) FlowTotals.initStorage += Node[j].newVolume; for (j = 0; j < Nobjects[LINK]; j++) FlowTotals.initStorage += Link[j].newVolume; StepFlowTotals = FlowTotals; // --- add contribution of minimum surface area (i.e., manhole area) // to initial storage under dynamic wave routing if ( RouteModel == DW ) { for (j = 0; j < Nobjects[NODE]; j++) { if ( Node[j].type != STORAGE && Node[j].initDepth <= Node[j].crownElev - Node[j].invertElev ) //(5.1.007) FlowTotals.initStorage += Node[j].initDepth * MinSurfArea; } } // --- initialize arrays to null LoadingTotals = NULL; QualTotals = NULL; StepQualTotals = NULL; NodeInflow = NULL; NodeOutflow = NULL; // --- allocate memory for WQ washoff continuity totals n = Nobjects[POLLUT]; if ( n > 0 ) { LoadingTotals = (TLoadingTotals *) calloc(n, sizeof(TLoadingTotals)); if ( LoadingTotals == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } for (j = 0; j < n; j++) { LoadingTotals[j].initLoad = massbal_getBuildup(j); LoadingTotals[j].buildup = 0.0; LoadingTotals[j].deposition = 0.0; LoadingTotals[j].sweeping = 0.0; LoadingTotals[j].infil = 0.0; LoadingTotals[j].bmpRemoval = 0.0; LoadingTotals[j].runoff = 0.0; LoadingTotals[j].finalLoad = 0.0; } } // --- allocate memory for nodal WQ continuity totals if ( n > 0 ) { QualTotals = (TRoutingTotals *) calloc(n, sizeof(TRoutingTotals)); StepQualTotals = (TRoutingTotals *) calloc(n, sizeof(TRoutingTotals)); if ( QualTotals == NULL || StepQualTotals == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } } // --- initialize WQ totals for (j = 0; j < n; j++) { QualTotals[j].dwInflow = 0.0; QualTotals[j].wwInflow = 0.0; QualTotals[j].gwInflow = 0.0; QualTotals[j].exInflow = 0.0; QualTotals[j].flooding = 0.0; QualTotals[j].outflow = 0.0; QualTotals[j].evapLoss = 0.0; QualTotals[j].seepLoss = 0.0; QualTotals[j].reacted = 0.0; QualTotals[j].initStorage = massbal_getStoredMass(j); } // --- initialize totals used over a single time step massbal_initTimeStepTotals(); // --- allocate memory for nodal flow continuity if ( Nobjects[NODE] > 0 ) { NodeInflow = (double *) calloc(Nobjects[NODE], sizeof(double)); if ( NodeInflow == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } NodeOutflow = (double *) calloc(Nobjects[NODE], sizeof(double)); if ( NodeOutflow == NULL ) { report_writeErrorMsg(ERR_MEMORY, ""); return ErrorCode; } for (j = 0; j < Nobjects[NODE]; j++) NodeInflow[j] = Node[j].newVolume; } return ErrorCode; }
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); } }