INTRO       18
_____________________Welcome to ROSE-HULMAN RESOURCES__________________________
..............a Thriving Electric Utility in Terre Haute, Indiana..............

RHR has a number of small turbine generators producing electricity for the
campus.  The load at Rose-Hulman must be served on demand.  That is, the
electricity demand is high during air conditioning season and quite small at
3:00 AM when only the double majors are studying.

Your assignment is to correctly dispatch the generators to minimize
the overall cost of electric energy delivered to Rose-Hulman.  This small
computer program will help you learn the basics of this important job.

You will have opportunities to change data, respond to questions & etc. 
The ESCAPE key will get you out of what you are doing.  While editing
data, you may use CTRL Right or Left Arrow to move to the next field.  The
editing is set up in typeover mode.
GENPOLY1    16
______________________FITTING DATA TO A POLYNOMIAL_____________________________

This program uses a cubic polynomial to represent the heat rate function. 
That is:

                 H(P) = h_3*P^3 + h_2*P^2 + h_1*P + h_0 

Where H(P) is the heat input in Million BTU per hour.  The polynomial
coeffecients are h_3, h_2, h_1, and h_0.  The power output of the generator is
designated as P in megawatthours per hour.

Typically, utilities run heat rate tests on generators on a regular basis. 
Then, somebody will fit that data into an economic dispatch program.  Your
next screen will give you opportunity to create your own data, or use
suggested data.  You may edit the suggested data however you like.
THECOSTOF1  12
_________________________ THE COST OF GENERATION ______________________________

In order to properly dispatch large electric generators, we need to know how
the energy input varies with output.  This relationship is:

                              Heat In = H(P)

This is a handy relationship because it is strictly based on generator
characteristics.  Generators require a considerable amount of heat input just
to get the machine spinning without producing any output.  From there, cost
increases with output.
THECOSTOF2   8
_________________________ THE COST OF GENERATION ______________________________


Once we know how the heat input varies with power output it is a simple matter
to multiply the heat input by the fuel cost.

                         Cost = F(P) = H(P) * Fuel Cost
THECOSTOF3  13
_________________________ THE COST OF GENERATION ______________________________



The final part of generation cost is the system losses.  Generators far away
must be penalized for the extra loss incurred moving electrical energy over
transmission lines.  This introduces a penalty factor.

                        Cost = F(P) * 1 / Penalty_Factor

This completes the cost equations for finding the cost as a function of
generators output.
GENERAL1     8
________________GENERAL REQUIREMENTS FOR FINDING MINIMUM COST_________________

To find the minimum cost, we must meet certain constraints.  First, the
generator may not run below its minimum output.  It also will not run above
its maximum output.  That is:

                             P_min < P_out < P_max

GENERAL2     8
________________GENERAL REQUIREMENTS FOR FINDING MINIMUM COST_________________

The second requirement is that all dispatchable generators, have the same
incremental cost.  In other words the first derivitave of the cost function of
all dispatchable generators is equal.  The incremental cost or lambdas of each
generator equals all the other units.

                             dF(Cost)/dPi =  lambda
GENERAL3     7
________________GENERAL REQUIREMENTS FOR FINDING MINIMUM COST_________________

Now we have the key constraints.  Find an incremental cost where the net output
is just what we need.  Make sure generators are working within their limits. 
We have minimum cost for a given set of generators on line when we meet these
conditions.
EQUALLAMBDA1 8
-------------------- Learning About Finding the MIMIMUM COST ------------------

This section introduces you to the concept minimum output cost occurs when all
dispatchable generators are operating at EQUAL INCREMENTAL cost.  That is, the
first derivative the cost function, the incremental cost or LAMBDA,  of all
dispatchable generators is equal.

Let's try a simple two generator system .....
EQUALLAMBDA2 14
---------------------- More About Finding the MIMIMUM COST -------------------

To visualize the equal incremental cost concept, we will take a simple two
generator system.  Each generator has it's own cost function, but both units
have the same minimum and maximum output levels.  The specific data are:

 UNIT    MIN_LOAD  MAX_LOAD           COST EQUATION
Unit 1
Unit 2

Let's look at two graphs while we try to meet a system load of 800 MW.  The
left graph is the total energy cost and the right graph is the incremental
output cost for each unit.  You will be asked to try finding the minimum 
cost by guessing the output of Unit 1.
MAKEAGUESS  12
---------------------------- Finding the Right Lambda -------------------------

Let's summarize what we have learned with a ten generator system.  We need to
dispatch all ten for minimum cost while meeting our system load of 3,000 MW.

We know minimum cost is achieved when all dispatchable generators have equal
incremental costs (lambdas).  We also know that we must not run the generators
below their minimum or above their maximum output.

With this information, we can guess a lambda and graphically estimate the
output of each generator.  After you guess a lambda, watch how that guess
affects the output of each generator.  Then see how well you met the load.
LOSSES1      8
___________________________ Accounting For Losses _____________________________

So far we have neglected losses.  Actually a generator that is many ohms away
from the load must be peanalized because of the extra losses.  To do this, we
introduce a loss factor, dPloss/dP.  Typically this data comes from load flow
data.  This program reads the data from a separate file and uses Stevenson's
method to calculate loss peanalties.  
BINARY1     15
One simple, effective way for iterating to a solution is to use a binary
technique.

 * Find the minimum and maximum possible lambdas for your particular
   mix of dispatchable generators.
 * Make your first guess for lambda right in the middle no matter what.
 * Calculate the output based on that lambda.
 * If you are short, move lambda up half the distance of the last guess or...
   move down if you ar generating too much.
 * Keep doing this halving the next move until you reach a solution.
 * Your are finished when the output matches the load within a convergence
   tolerence.

The next few screens show a "C" code segment that does this work.  Then you
will have a chance to see a plot of an iteration summary.
BINARY2    22
/* ------------------------- BINARY SOLUTION ----------------------------- */
/* THIS METHOD STARTS MIDWAY BETWEEN THE POSSIBLE RANGE OF LAMBDAS FOR     */
/* THE CASE.  EACH ITERATION MOVES HALF THE DISTANCE OF THE LAST ONE.      */
/* ----------------------------------------------------------------------- */
char binary_solution(void)
{
     char      solved;             /* SOLUTION FLAG                        */
     int       i;                  /* COUNTER                              */
     float     del_lambda;         /* LAMBDA INCREMENT                     */
     float     tolerance;          /* SOLUTION TOLERANCE                   */
     float     mw_error;           /* MW ERROR                             */

     /* START WITH LAMBDA AT THE MIDDLE  */
     lambda = (max_lambda + min_lambda) / 2;

     /*  START THE INCREMENT AT 1/4 THE RANGE OF LAMBDAS  */
     del_lambda = (max_lambda - min_lambda) / 4;

     /* SET UP ITERATION VARIABLES */
     solved = 'F';
     tolerance = TOL;    /* TOL is defined by a compiler directive */
     i = 0;
BINARY3    16
______________________ Here is Page 2 of the Program _________________________

     /* START LOOPING THROUGH THE ITERATIONS */
     while( (i < MAXITERATIONS) && (solved == 'F') )
          {
          /* CALCULATE THE OUTPUT FOR THIS GUESS */
          calc_output();

          /* SEE IF WE MET THE SYSTEM LOAD */
          if( fabs(mw_error) < tolerance)
               {
               /* WE FOUND A SOLUTION */
               solved = 'T';
               }

Page three shows what we do if the iteration did not make it.
BINARY4    22
     else
               {
               /* NO GOOD - TRY AGAIN */
               if( mw_error < 0 )
                    {
                    /* RATCHET UP ONE INCREMENT IF WE ARE SHORT */
                    lambda = lambda + del_lambda;
                    }
               if( mw_error > 0 )
                    {
                    /* RATCHET DOWN ONE INCREMENT IF WE HAVE EXCESS */
                    lambda = lambda - del_lambda;
                    }

               /* TRUE BINARY - HALVE THE INCREMENT FOR THE NEXT ITERATION */
               del_lambda = del_lambda / 2;
               i++;
               }
          }

     return( solved );
}
BINARY5     14
__________________________ A SECOND SOLUTION METHOD ___________________________

The binary solution is nice because it always will work.  The problem with it
is that it is dumb.  You may have noticed how iteration #2 is always halfway
above or halfway below the first guess.

It is oftern desirable to get faster solutions.  One way is to use information
from your previous guess and compare it to the latest guess.  You can find the
slope of the line and estimate your next guess on some percentage of the rate
of change dP/dLambda.  This is sometimes faster depending on what percentage of
dP/dLambda you move.  It also has the opportunity to BLOW UP for certain
generator cost functions.