@@ -1395,6 +1395,7 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
13951395 int *lpgoalrow=new int [_nGoals]; // index of goal equation for all user-specified goals
13961396
13971397 double **aQiterHist=NULL ,**ahiterHist=NULL ;
1398+ bool *aInfeasHist= new bool [_maxIterations];
13981399
13991400 aQiterHist=new double *[_pModel->GetNumSubBasins ()];
14001401 ahiterHist=new double *[_pModel->GetNumSubBasins ()];
@@ -1409,7 +1410,9 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
14091410 ahiterHist[p][i]=0.0 ;
14101411 }
14111412 }
1412-
1413+ for (int i = 0 ; i < _maxIterations; i++) {
1414+ aInfeasHist[i]=false ;
1415+ }
14131416 // instantiate linear programming solver
14141417 // ----------------------------------------------------------------
14151418 lp_lib::lprec *pLinProg;
@@ -1448,8 +1451,9 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
14481451 }
14491452
14501453 // Set lower bounds of flows (Q) to something a bit less than zero for cushion
1454+ // can't do this- messes up weir formulation
14511455 // ----------------------------------------------------------------
1452- int nESB = 0 ;
1456+ /* int nESB = 0;
14531457 for (int pp = 0; pp<pModel->GetNumSubBasins(); pp++)
14541458 {
14551459 p =pModel->GetOrderedSubBasinIndex(pp);
@@ -1469,14 +1473,15 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
14691473 pSB=pModel->GetSubBasin(p);
14701474 if (pSB->IsEnabled() && (pSB->GetReservoir()!=NULL))
14711475 {
1472- retval=lp_lib::set_lowbo (pLinProg,GetDVColumnInd (DV_QOUTRES,res_count), -0.001 );
1473- ExitGracefullyIf (retval!=1 ," SolveManagementProblem::Error adding stage lower bound" ,RUNTIME_ERR);
1474- res_count++;
1476+ retval=lp_lib::set_lowbo(pLinProg,GetDVColumnInd(DV_QOUTRES,res_count), -0.001);
1477+ ExitGracefullyIf(retval!=1,"SolveManagementProblem::Error adding stage lower bound",RUNTIME_ERR);
1478+ res_count++;
14751479 }
1476- }
1480+ }*/
1481+
14771482 // Set lower bounds of stages to min stage -2m
14781483 // ----------------------------------------------------------------
1479- res_count=0 ;
1484+ int res_count=0 ;
14801485 for (int pp = 0 ; pp<pModel->GetNumSubBasins (); pp++)
14811486 {
14821487 p =pModel->GetOrderedSubBasinIndex (pp);
@@ -1798,9 +1803,9 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
17981803 RHS+=U_n*pSB->GetSpecifiedInflow (t-n*Options.timestep );
17991804 }
18001805 for (int n = 1 ; n < pSB->GetLatHistorySize (); n++) {
1801- RHS += pSB->GetUnitHydrograph ()[n] * pSB->GetLatHistory ()[n-1 ]; // [n-1] is because this inflow history has not yet been updated
1806+ RHS += pSB->GetUnitHydrograph ()[n] * max ( pSB->GetLatHistory ()[n-1 ], 0.0 ) ; // [n-1] is because this inflow history has not yet been updated
18021807 }
1803- RHS+=aSBrunoff[p]/(tstep*SEC_PER_DAY)*pSB->GetUnitHydrograph ()[0 ]; // [m3]->[m3/s]
1808+ RHS+=max ( aSBrunoff[p], 0.0 ) /(tstep*SEC_PER_DAY)*pSB->GetUnitHydrograph ()[0 ]; // [m3]->[m3/s]
18041809 }
18051810 else // assimilating - skip mass balance
18061811 {
@@ -1964,11 +1969,11 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
19641969 // ------------------------------------------------------------------------
19651970 // linearized storage -discharge curve
19661971 // Qout = Qout_guess + dQ/dh * (h-h_guess) if h>h_sill
1967- // Qout = 0 if h<h_sill
1972+ // Qout = 0 if h<= h_sill
19681973 // handled via 5 constraint equations
19691974
1970- const double LARGE_NUMBER=1e6 ;
1971- const double LARGE_NUMBER2=1000 ;
1975+ const double LARGE_NUMBER=1e6 ; // for flow variables
1976+ const double LARGE_NUMBER2=100 ; // for stage variables
19721977
19731978 // ------------------------------------------------------------------------
19741979 // Eqns 1 & 2 : h^n+1 - M*(1-b) <= h_sill
@@ -2025,7 +2030,8 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
20252030 // Q^n+1 <= Qout_guess + dQ/dh * (h^n+1-h_guess) + M(b)
20262031 // Q^n+1 - dQ/dh* h^n+1 + Mb >= [Qout_guess - dQ/dh * h_guess]
20272032 // Q^n+1 - dQ/dh* h^n+1 - Mb <= [Qout_guess - dQ/dh * h_guess]
2028- // dQ << M
2033+ // dQ << M
2034+ // enforces stage-discharge linearization when b==0
20292035 // ------------------------------------------------------------------------
20302036
20312037 // col_ind[0]=GetDVColumnInd(DV_QOUTRES,_aResIndices[p]); row_val[0]=1.0;
@@ -2223,6 +2229,7 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
22232229 lp_lib::set_verbose (pLinProg,IMPORTANT);
22242230
22252231 int nInfeasibleIters=0 ;
2232+ bool lastInfeasible;
22262233 int iter=0 ;
22272234 double norm;
22282235 do
@@ -2242,6 +2249,12 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
22422249 {
22432250 if (_do_debug_level>0 ){ cout<<" LP instability found." <<endl; }
22442251 nInfeasibleIters++;
2252+ lastInfeasible=true ;
2253+ aInfeasHist[iter]=true ;
2254+ }
2255+ else {
2256+ lastInfeasible=false ;
2257+ aInfeasHist[iter]=false ;
22452258 }
22462259
22472260 // assign decision variables
@@ -2293,6 +2306,7 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
22932306 }
22942307
22952308 cout<<" Iteration Sequence: " <<endl;
2309+ cout<<" >infeasible?: " ; for (int i = 0 ; i <= iter; i++) { cout << aInfeasHist[i] << " " ; }cout << endl;
22962310 for (int p = 0 ; p < pModel->GetNumSubBasins (); p++) {
22972311 if (pModel->GetSubBasin (p)->GetReservoir ()!=NULL ){
22982312 long long SBID=pModel->GetSubBasin (p)->GetID ();
@@ -2334,15 +2348,18 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
23342348 // ----------------------------------------------------------------
23352349 double value;
23362350 dv_type typ;
2351+ double wobble=0.0 ;
23372352 double relax=0.0 ;
23382353 for (int i=0 ;i<_nDecisionVars;i++)
23392354 {
23402355 p = _pDecisionVars[i]->p_index ;
23412356 value = _pDecisionVars[i]->value ;
23422357 typ = _pDecisionVars[i]->dvar_type ;
2358+ // if (lastInfeasible){wobble=0.005;}
2359+ // else {wobble=0.0;}
23432360
2344- if (typ == DV_STAGE) {ahiterHist[p][iter]=h_iter[p]; h_iter[p]=(1.0 -relax)*value+(relax)*h_iter[p]; }
2345- else if (typ == DV_QOUT ) {aQiterHist[p][iter]=Q_iter[p]; Q_iter[p]=(1.0 -relax)*value+(relax)*h_iter [p]; }
2361+ if (typ == DV_STAGE) {ahiterHist[p][iter]=h_iter[p]; h_iter[p]=(1.0 -relax)*value+(relax)*h_iter[p]+wobble ; }
2362+ else if (typ == DV_QOUT ) {aQiterHist[p][iter]=Q_iter[p]; Q_iter[p]=(1.0 -relax)*value+(relax)*Q_iter [p]; }
23462363 }
23472364
23482365 /* for (int p = 0; p < pModel->GetNumSubBasins(); p++) {
@@ -2462,9 +2479,15 @@ void CDemandOptimizer::SolveManagementProblem(CModel *pModel, const optStruct &O
24622479 delete [] lpgoalrow;
24632480 delete [] aDivert;
24642481 delete [] aDivGuess;
2482+ delete [] aInfeasHist;
2483+ for (p = 0 ; p < _pModel->GetNumSubBasins (); p++) {
2484+ delete [] aQiterHist[p]; delete [] ahiterHist[p];
2485+ }
2486+ delete [] aQiterHist;
2487+ delete [] ahiterHist;
24652488
24662489 // set state variables corresponding to decision variables
2467- // SHOULD REALLY ONLY UPDATE DELIVERY, RES_EXTRACT, AND RESERVOIR OUTFLOW - ADD SWITCH TO HAVE OPT MODEL GENERATE STATE VARS OR REGULAR RAVEN SETUP
2490+ // SHOULD REALLY ONLY UPDATE DELIVERY, RES_EXTRACT, AND RESERVOIR OUTFLOW - ADD SWITCH TO HAVE OPT MODEL GENERATE STATE VARS OR REGULAR RAVEN SETUP?
24682491 // ----------------------------------------------------------------
24692492 double value;
24702493 dv_type typ;
@@ -2726,25 +2749,41 @@ void CDemandOptimizer::WriteLPSubMatrix(lp_lib::lprec* pLinProg,string file, con
27262749 for (int i = 0 ; i < ncols; i++) {
27272750 LPMAT<<lp_lib::get_col_name (pLinProg,i+1 )<<" ," ;
27282751 }
2729- LPMAT<<" compare,RHS" <<endl;
2752+ LPMAT<<" compare,RHS,,prevLHS,test " <<endl;
27302753
27312754 string comp;
27322755 REAL *val=new REAL [ncols+1 ];
2756+ double sumprod;
2757+ double RHS;
2758+ bool bo;
27332759 for (int j=0 ; j<=nrows; j++)
27342760 {
2761+ sumprod=0.0 ;
27352762 LPMAT<<lp_lib::get_row_name (pLinProg,j)<<" ," ;
27362763 lp_lib::get_row (pLinProg,j,val);
2764+ RHS=lp_lib::get_rh (pLinProg,j);
27372765 for (int i = 0 ; i < ncols; i++) {
27382766 LPMAT<<val[i+1 ]<<" ," ;
2767+ sumprod+=val[i+1 ]*_pDecisionVars[i]->value ; // LHS vector
27392768 }
27402769 int ctype=lp_lib::get_constr_type (pLinProg,j);
2741- if (ctype==1 ){comp=" <=" ; }
2742- else if (ctype==2 ){comp=" >=" ; }
2743- else if (ctype==3 ){comp=" ==" ; }
2770+ if (ctype==1 ){comp=" <=" ; bo = (sumprod <=RHS+REAL_SMALL); }
2771+ else if (ctype==2 ){comp=" >=" ; bo = (sumprod >=RHS-REAL_SMALL); }
2772+ else if (ctype==3 ){comp=" ==" ; bo = ( fabs (sumprod-RHS)/ fabs ( 0.5 *(RHS+sumprod))< 0.01 ); }
27442773
27452774 LPMAT<<comp<<" ," ;
2746- LPMAT<<lp_lib::get_rh (pLinProg,j)<<endl;
2775+ LPMAT<<RHS<<" ," ;
2776+ LPMAT<<" ," <<sumprod<<" ," ;
2777+ if (bo){LPMAT<<" TRUE" ;}else {LPMAT<<" FALSE" ; }
2778+ LPMAT<< endl;
2779+ }
2780+ LPMAT<<endl;
2781+ LPMAT<<" last_solution," ;
2782+ for (int i=0 ;i<_nDecisionVars;i++){
2783+ LPMAT<<_pDecisionVars[i]->value <<" ," ;
27472784 }
2785+ LPMAT<<endl;
2786+
27482787 LPMAT.close ();
27492788 delete [] val;
27502789}
0 commit comments