$title  An MPSGE Template for Renewable Portfolio Standards


An Email Question about Renewable Portfolio Standards

My sincere apologies for bothering you with what must be a trivial
question, namely, the proper interpretation for the level value of an
endogenous subsidy which is greater than unity. Is this merely a sign
that my model ill-posed, or is there some other interpretation?

The back story is that I am trying to simulate a renewable portfolio 
standard (RPS) within a CGE model. I have a balanced SAM whose electric 
power sector has been disaggregated into various generation 
technologies, which I use to calibrate a representative-agent model of 
the economy. Recall that an RPS is a two-part instrument in which 
qualifying renewables enjoy a subsidy, the revenue for which is raised 
through a tax on conventional generation. I implement this using two 
scalar auxiliary equations: RPS_SUB, an endogenous subsidy to meet the 
target level of renewable penetration (given by RENEWABLE_PORTFOLIO_STD 
= 20%), and RPS_TAX, the corresponding endogenous tax on conventional 

Here is the generators' production block:

<lots of MPSGE code>

The first problem is that to meet even a 10% target, the level value
of RPS_SUB is much larger than unity. Even this target is pretty
stringent, as renewables make up only 1.6% of net generation in the
benchmark. To test whether anything is wrong I have simulated the
model with only the subsidy and no tax component (by setting the flag
TAXCOMP to zero), and the value of RPS_SUB is still large. The model
solves normally and the final statistics look OK.

The second problem follows, which is that the level of RPS_TAX which
is required to finance that level of subsidy exceeds 60%! Note that in
the second side-constraint I am assuming that the output price of each
type of generator which MPSGE reports is *net* of any tax or subsidy.
Is this correct?

Any assistance you might be able to provide would be greatly

"Je N'ai fait celle-ci plus longue que parceque je n'ai pas eu le
loisir de la faire plus courte.-- I have only made this letter rather
long because I have not had time to make it shorter." Pascal. Lettres
provinciales, 16, Dec.14,1656. Cassell's Book of Quotations,
London,1912. P.718. 

"Not that the story need be long, but it will take a long while to
make it short." Thoreau. Letter to a Friend. 

In other words, I don't have time to debug your code, but I can more
easily write a little template model which shows you how I would
implement a portfolio standard.  The burden of understanding how this
works then rests with your willingness to go through my code,
something which is a very different burden sharing arrangement than
had I taken the time to go through your model.  I am always happy to
point the way, but I often don't have time to go with you step by

Let me begin with the big issue here.  MPSGE offers "auxiliary
variables" as a means of coping with exotic challenges which arise in
general equilibrium analysis.  These are particularly useful when
dealing with market failures.  It is generally a good idea, however,
to work within the standard Arrow-Debreu paradigm whenever possible.
This is one such application in which while it is possible but not
advisable to resort to auxiliary variables.

Now, let me describe my template application.  
In this little model electricity generation is associated with 100
generating facilities, each of which has the same capacity.  Units
have different operating costs, both associated with their technology
characteristics and other idosyncratic features of each plant.  Units
are dispatched in merit order utilizing Mathiesen's complementarity
format to integrate the complementary slackness features directly into
the equilibrium problem.  (See this working paper and the
associated GAMS files.)

A two-dimensional set (a "tuple") pt(t,f) associates generating units
t with fuel characteristics f.  A renewable portfolio standard is a
constraint which requires that units based on a particular set of
fuels supply a minimum fraction of the delivered power:

        sum(pt(t,rps), x(t)) =g= phi * sum(t,x(t));

The trick to implementing this constraint in MPSGE is to identify
which of these coefficients on the $prod:x(t) block are inputs and
which are outputs.

The way to think of this is to imagine a permit system which
implements the RPS policy.  Each time that someone generates a KWH of
electricity from a renewable plant, the manager receives a RPS permit.
At the same time, any time that any plant (including a renewable
plant) produces 1 KWH of electricity, they must surrender phi permits,
where phi is the renewable portfolio standard.

In linear programming parlance, the RPS rule introduces a "blending
constraint", and it is notable that blending constraints are linearly
homogeneous -- there is no RHS constant.  In economic terms, this
means that the RPS system redistributes funds between power plant
operators, but any impact on household incomes is purely indirect,
operating only through the price of the delivered electricity.  In
other words, there are no pure rents produced by the RPS, and perhaps
this is one reason that these sorts of rules are so popular.  


set     f       Electric power technologies /coal,gas,nucl,wind,solar,hydro/,
        rps(f)  Renewable power technologies /wind,solar,hydro/,
        t       Power plants (for simplicity equal capacity) /p1*p100/,
        pt(t,f) An association of plants to fuels (one to one);

$eolcom !

parameter       pi(f)   Fraction of plants in each type
        /coal   0.4
         gas    0.2
         nucl   0.2     
         wind   0.05    !       
         solar  0.05    !  Renewables are only 20% of capacity.
         hydro  0.10/;  !  Higher targets require idling of capacity.

*       Convert the fractions to a cumulative distribution:

loop(f, pi(f) = pi(f-1) + pi(f););  display pi;

*       Produce a tuple which maps plants to fuels in numbers
*       which are consistent with the plant fractions:

pt(t,f) = yes$(ord(t)/card(t) > pi(f-1) and ord(t)/card(t) <= pi(f));

parameter       nplant(f)       Number of plants by type;
nplant(f) = sum(pt(t,f),1);
display nplant;

set bug(t);
bug(t) = yes$(1-sum(pt(t,f),1));
display bug;

parameter       ac(f)   Average cost /
                        coal    10
                        gas     20
                        nucl    10
                        wind    40
                        solar   50
                        hydro   60 /;

parameter       tc(t)   Technology cost (with random differences);
loop(pt(t,f),   tc(t) = ac(f) * normal(1,0.2);); display tc;

parameter       rpsout(t)       Coefficient for RPS system,
                phi             RPS target share,
                delta(t)        Switch for introducing permit system,
                limit           Target associated with permit system;

*       Base year equilibrium has no RPS constraint nor permits:

limit = 0;
delta(t) =0;
phi = 0;
rpsout(t) = 0;


        c       ! Consumption of goods and leisure
        y       ! Other production
        x(t)    ! Electricity generation

        pc              ! Price of consumption
        py              ! Price of output
        pe              ! Price of energy
        pl              ! Price of leisure
        pk              ! Price of capital 
        pcap(t)         ! Price of electricity generating capacity
        prps$phi        ! Shadow price on renewables
        plim$limit      ! Shadow price on efficient instrument

        ra      ! Representative agent

*       Final consumption combines goods and leisure:

$prod:c  s:1
        o:pc    q:100
        i:pl    q:50
        i:py    q:50

*       Macro production trades off energy use with value-added:

$prod:y  s:0.5  va:1
        o:py    q:50
        i:pe    q:2     
        i:pl    q:30
        i:pk    q:18

*       Electricity generation:

$prod:x(t)  s:0
        o:pe            q:2
        i:py            q:(tc(t)/100)   ! Scaling here to match macro
        i:pcap(t)       q:1             ! units -- benchmark output approx. = 2

*       RPS policy instruments, including both 
*       input and output  coefficients:

        o:prps          q:rpsout(t)
        i:prps          q:phi

*       Efficient policy instrument:

        i:plim          q:delta(t)

*       Final demand:

        e:pk            q:18
        e:pl            q:80
        e:pcap(t)       q:0.05

*       When we have a permit system, rents on the permits 
*       are return lump-sum:

        e:plim          q:limit

$sysinclude mpsgeset aaelec

*       The model is not precisely calibrated.  We therefore need to 
*       solve for a benchmark equilibrium and cannot use the debugging
*       trick of setting the iteration limit to zero:

$include AAELEC.GEN
solve aaelec using mcp;

parameter       results         Summary report;
results("bmk",f) = sum(pt(t,f),x.l(t)*2);
results("bmk","PE") = pe.l/pc.l;
results("bmk","pl") = pl.l/pc.l;
results("bmk","pk") = pk.l/pc.l;
results("bmk","c") = c.l;
results("bmk","e") = sum(t,x.l(t)*2);
display results;

*       Set the solvelink to 2 so that GAMS remains in memory
*       during the solution process and does not need to reload
*       after each solution:

aaelec.solvelink = 2;

*       The shadow prices on the RPS is initially omitted from the
*       model.  We need to set the level value of this price to zero
*       so that we properly report the initial price:

prps.l = 0;

*       Consider a range of RPS targets from 0% to 50%:

set     rpslvl  Level of the renewable portfolio standard (%) /0*50/;


*       Establish the target share here:

        phi = 0.01*(ord(rpslvl)-1);

$include AAELEC.GEN
        solve aaelec using mcp;

*       Record results for this RPS target:

        results(rpslvl,f) = sum(pt(t,f),x.l(t)*2);
        results(rpslvl,"rpssbd") = 100*prps.l/pe.l*(1-phi)/2;
        results(rpslvl,"rpstax") = 100*prps.l/pe.l*phi/2;
        results(rpslvl,"E")  = sum(t, x.l(t)*2);
        results(rpslvl,"PE") = pe.l/pc.l;
        results(rpslvl,"pl") = pl.l/pc.l;
        results(rpslvl,"pk") = pk.l/pc.l;
        results(rpslvl,"c") = c.l;

*       As part of the reporting, record the emission level from
*       the non-RPS plants.  These values will permit us to compute
*       the excess economic cost of the RPS policy, as we can compare
*       it with a first-best permit system (see below):

        results(rpslvl,"emit") = sum(pt(t,f)$(not rps(f)), X.L(t));

*       Install the RPS output coefficients for those plants
*       which are fueled with renewable inputs:

        loop(pt(t,rps), rpsout(t) = 1;);


*       Turn off the RPS instrument:

rpsout(t) = 0;  phi = 0;

*       Turn on the permit system which simply places an upper
*       bound on the non-renewable generation:

loop(pt(t,f)$(not rps(f)), delta(t) = 1;);

*       Go back through the same set of emission targets so that
*       we can evaluate how the excess cost is related to the 
*       renewable target:


        limit = results(rpslvl,"emit");

$include AAELEC.GEN
        solve aaelec using mcp;

*       Record a few characteristics of these equilibria: energy 
*       price, permit price, and aggregate consumption:

        results(rpslvl,"PE*") = pe.l/pc.l;
        results(rpslvl,"plim") = 100 * plim.l/pe.l * 1/2;
        results(rpslvl,"E*")  = sum(t, x.l(t)*2);
        results(rpslvl,"c*") = c.l;
display results;

*       Produce some output using GNUPLOT:

parameter       summary         Summary of impacts;

*       It took a bit of fiddling to determine that these outputs
*       provide insights into the economics of the policy measures:

summary(rpslvl,"sbd%")  = results(rpslvl,"rpssbd");
summary(rpslvl,"tax%")  = results(rpslvl,"rpstax");
summary(rpslvl,"pe")    = 100 * (results(rpslvl,"pe")/results("bmk","pe")-1);
summary(rpslvl,"plim")  = results(rpslvl,"plim");
summary(rpslvl,"pe*")   = 100 * (results(rpslvl,"pe*")/results("bmk","pe")-1);
summary(rpslvl,"e")     = 100 * (results(rpslvl,"e")/results("bmk","e")-1);
summary(rpslvl,"e*")    = 100 * (results(rpslvl,"e*")/results("bmk","e")-1);

parameter       welfare         Comparison of Welfare impacts;

welfare(rpslvl,"RPS")     = 100 * (results(rpslvl,"c")/ results("bmk","c")-1);
welfare(rpslvl,"Permits") = 100 * (results(rpslvl,"c*")/results("bmk","c")-1);

*       Define the domain and the labels for the plots:

set rpslbl(rpslvl) /10,20,30,40,50/;
$setglobal domain rpslvl
$setglobal labels rpslbl

*       Issue some GNUPLOT commands to provide a nicer plot:

$setglobal gp_opt0 "set xlabel '% RPS share'"
$setglobal gp_opt1 "set ylabel '% change'"
$setglobal gp_opt2 "set key outside width 3"
$setglobal gp_opt3 "set grid"

$setglobal gp_opt4 "set title 'Economic Impacts of RPS'"
$libinclude plot summary

$setglobal gp_opt4 "set title 'Welfare Impact of RPS'"
$libinclude plot welfare

*       After having generated the plots on the screen, generate 
*       the same plots as PNG files:

$setglobal batch yes

$setglobal gp_opt5 "set term png"

$setglobal gp_opt4 "set title 'Economic Impacts of RPS'"
$setglobal gp_opt6 "set output 'impacts.png'"
$libinclude plot summary

$setglobal gp_opt4 "set title 'Welfare Impact of RPS'"
$setglobal gp_opt6 "set output 'welfare.png'"
$libinclude plot welfare