/
national_account.cpp
executable file
·319 lines (277 loc) · 11.7 KB
/
national_account.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/*
* LEGAL NOTICE
* This computer software was prepared by Battelle Memorial Institute,
* hereinafter the Contractor, under Contract No. DE-AC05-76RL0 1830
* with the Department of Energy (DOE). NEITHER THE GOVERNMENT NOR THE
* CONTRACTOR MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY
* LIABILITY FOR THE USE OF THIS SOFTWARE. This notice including this
* sentence must appear on any copies of this computer software.
*
* EXPORT CONTROL
* User agrees that the Software will not be shipped, transferred or
* exported into any country or used in any manner prohibited by the
* United States Export Administration Act or any other applicable
* export laws, restrictions or regulations (collectively the "Export Laws").
* Export of the Software may require some form of license or other
* authority from the U.S. Government, and failure to obtain such
* export control license may result in criminal liability under
* U.S. laws. In addition, if the Software is identified as export controlled
* items under the Export Laws, User represents and warrants that User
* is not a citizen, or otherwise located within, an embargoed nation
* (including without limitation Iran, Syria, Sudan, Cuba, and North Korea)
* and that User is not otherwise prohibited
* under the Export Laws from receiving the Software.
*
* Copyright 2011 Battelle Memorial Institute. All Rights Reserved.
* Distributed as open-source under the terms of the Educational Community
* License version 2.0 (ECL 2.0). http://www.opensource.org/licenses/ecl2.php
*
* For further details, see: http://www.globalchange.umd.edu/models/gcam/
*
*/
/*!
* \file national_account.cpp
* \ingroup Objects
* \brief The National ccount class source file.
* \author Pralit Patel
* \author Sonny Kim
*/
#include "util/base/include/definitions.h"
#include <cassert>
#include "containers/include/national_account.h"
#include "util/base/include/ivisitor.h"
#include "util/base/include/xml_helper.h"
#include "util/base/include/xml_parse_helper.h"
#include "util/base/include/util.h"
#include "util/logger/include/ilogger.h"
#include "demographics/include/demographic.h"
#include "containers/include/iinfo.h"
using namespace std;
extern Scenario* scenario;
//! Default Constructor
NationalAccount::NationalAccount():
// Size the accounts to one after the last valid value in the vector,
// represented by END.
mAccounts( END, 0 )
{
}
NationalAccount* NationalAccount::cloneAndInterpolate( const int aNewYear ) const {
NationalAccount* newNationalAccount = new NationalAccount();
newNationalAccount->mYear = aNewYear;
newNationalAccount->mAccounts = this->mAccounts;
return newNationalAccount;
}
/*! \brief Get the XML node name in static form for comparison when parsing XML.
*
* This public function accesses the private constant string, XML_NAME.
* This way the tag is always consistent for both read-in and output and can be easily changed.
* The "==" operator that is used when parsing, required this second function to return static.
* \note A function cannot be static and virtual.
* \author Josh Lurz, James Blackwood
* \return The constant XML_NAME as a static.
*/
const std::string& NationalAccount::getXMLNameStatic() {
const static string XML_NAME = "nationalAccount";
return XML_NAME;
}
//! Return year of national account
int NationalAccount::getYear() const {
return mYear;
}
//! Returns name (year as a string)
const std::string NationalAccount::getName() const {
return util::toString( mYear );
}
bool NationalAccount::XMLParse( rapidxml::xml_node<char>* & aNode ) {
/*! \pre make sure we were passed a valid node. */
assert( node );
string nodeName = XMLParseHelper::getNodeName(aNode);
if ( nodeName == enumToXMLName( SAVINGS_RATE ) ) {
setAccount( SAVINGS_RATE, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( CAPITAL_STOCK ) ) {
setAccount( CAPITAL_STOCK, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( DEPRECIATION_RATE ) ) {
setAccount( DEPRECIATION_RATE, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( CAPITAL_ENERGY_INV) ) {
setAccount( CAPITAL_ENERGY_INV, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( GDP ) ) {
setAccount( GDP, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( LABOR_WAGES ) ) {
setAccount( LABOR_WAGES, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( LABOR_FORCE_SHARE ) ) {
setAccount( LABOR_FORCE_SHARE, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( CAPITAL_NET_EXPORT ) ) {
setAccount( CAPITAL_NET_EXPORT, XMLParseHelper::getValue<double>( aNode ) );
}
else if ( nodeName == enumToXMLName( TOTAL_FACTOR_PRODUCTIVITY ) ) {
setAccount( TOTAL_FACTOR_PRODUCTIVITY, XMLParseHelper::getValue<double>( aNode ) );
}
else {
return false;
}
return true;
}
//! Output debug info to XML
void NationalAccount::toDebugXML( const int period, ostream& out, Tabs* tabs ) const {
XMLWriteOpeningTag( getXMLNameStatic(), out, tabs );
for( int i = 0; i < NationalAccount::END; ++i ) {
XMLWriteElement( getAccountValue( static_cast< NationalAccount::AccountType >( i ) ),
enumToXMLName( static_cast< NationalAccount::AccountType >( i ) ),
out, tabs );
}
XMLWriteClosingTag( getXMLNameStatic(), out, tabs );
}
void NationalAccount::completeInit() {
}
/*!
* \brief Complete initializations for the national account for base year
*/
void NationalAccount::completeInitHist( ) {
}
/*!
* \brief Complete initializations for the national account
*/
void NationalAccount::initCalc( const NationalAccount* aNationalAccountPrevious, const int aPeriod ) {
const Modeltime* modeltime = scenario->getModeltime();
// note these are last period rates
// TODO: may want to use current period savings and depreciation rates instead
double savings_rate = aNationalAccountPrevious->getAccountValue(SAVINGS_RATE);
double depreciation_rate = aNationalAccountPrevious->getAccountValue(DEPRECIATION_RATE);
double prevGDP = aNationalAccountPrevious->getAccountValue(GDP);
double capital = aNationalAccountPrevious->getAccountValue(CAPITAL_STOCK);
double prevEneInv = aNationalAccountPrevious->getAccountValue(CAPITAL_ENERGY_INV);
double prevConsDurableInv = aNationalAccountPrevious->getAccountValue(CONSUMER_DURABLE_INV);
// "move" consumer durable investment value from consumption to investment by inflating the
// savings rate to accommodate so that it can be included in the investment constraint
int prevPeriod = aPeriod - 1;
if(prevPeriod <= modeltime->getFinalCalibrationPeriod()) {
mConsumerDurableSRAdj = prevConsDurableInv / prevGDP;
}
else {
mConsumerDurableSRAdj = aNationalAccountPrevious->mConsumerDurableSRAdj;
}
mAccounts[SAVINGS] = prevGDP * (savings_rate + mConsumerDurableSRAdj); // annual savings based on lagged gdp
// CAPITAL_NET_EXPORT could be significantly negative (from historical data) so we
// should take care to ensure it doesn't take the "investment" negative.
mAccounts[INVESTMENT] = std::max(mAccounts[SAVINGS] + mAccounts[CAPITAL_NET_EXPORT], 0.0);
mAccounts[DEPRECIATION] = capital * depreciation_rate; // annual depreciation based on lagged capital
// Calculate for future periods only
if( aPeriod > modeltime->getFinalCalibrationPeriod() ){
// Depreciate capital and add new investments.
// Calculate annual changes for cumulative capital stock.
// Assumes constant GDP within period.
// Given capital stock is cumulative we need to apply the annual changes for
// each year in the time step.
double savings = mAccounts[INVESTMENT] - prevEneInv - prevConsDurableInv;
for(unsigned int i=0; i < scenario->getModeltime()->gettimestep(aPeriod); ++i){
capital = capital * (1 - depreciation_rate) + savings;
}
// protect against negative capital stock, note: in such a case the social
// account matrix will not balance thus signaling an issue
const double MIN_CAPITAL_STOCK = 100.0;
mAccounts[CAPITAL_STOCK] = std::max(capital, MIN_CAPITAL_STOCK);
}
}
/*!
* \brief Post calculations for the national account
*/
void NationalAccount::postCalc( ) {
mAccounts[ GDP_PER_CAPITA ] = mAccounts[GDP] / mAccounts[POPULATION];
}
/*!
* \brief Post calculations for the national account for historical periods
*/
void NationalAccount::postCalcHist( ) {
// Historical GDP is read-in, remove energy net exports to determine
// domestic GDP.
// Add energy expenditure to domestic GDP for gross output.
mAccounts[ GROSS_OUTPUT ] = mAccounts[GDP] - mAccounts[ENERGY_NET_EXPORT] ;
}
/*!
* \brief Add to the value for the national account specified by the account type key.
* \param aType The account which will be added to.
* \param aValue The value which will be added to account aType.
*/
void NationalAccount::addToAccount( const AccountType aType, const double aValue ){
mAccounts[ aType ] += aValue;
}
/*!
* \brief Set the value for the national account specified by the account type key.
* \param aType The account for which value will be set.
* \param aValue The value which will be set to account aType.
*/
void NationalAccount::setAccount( const AccountType aType, const double aValue ){
mAccounts[ aType ] = aValue;
}
/*!
* \brief Get the value for the national account specified by the account type key.
* \param aType The account who's value will be returned.
* \return The current value of the account aType.
*/
double NationalAccount::getAccountValue( const AccountType aType ) const {
assert( aType < END );
return mAccounts[ aType ];
}
/*!
* \brief Reset the national account values
* \note The accounts TRANSFERS and INVESTMENT_TAX_CREDIT do not get reset.
*/
void NationalAccount::reset() {
// Clear the values.
mAccounts.clear();
mAccounts.resize( END );
}
/*!
* \brief Convert between the NationalAccount enum type to the XML String representation
* \param aType The enum NationalAccount type
* \return The XML string representation of the type
* \author Pralit Patel
*/
const string& NationalAccount::enumToXMLName( const AccountType aType ) const {
/*! \pre aType is a valid account type. */
assert( aType < END );
// Create a static array of values. This will only on the first entrance to
// the function since this is a const static.
const static string names[] = {
"savings-rate",
"depreciation-rate",
"savings",
"investment",
"depreciation",
"capital-stock",
"energy-investment",
"consumer-durable",
"GDP",
"value-added",
"gross-output",
"labor-wages",
"labor-force",
"labor-force-share",
"total-factor-productivity",
"fac-share-labor",
"fac-share-capital",
"fac-share-energy",
"population",
"gdp-per-capita",
"gdp-per-capita-ppp",
"energy-service",
"energy-service-value",
"energy-net-export",
"materials-net-export",
"capital-net-export"
};
// Return the string in the static array at the index.
return names[ aType ];
}
// for reporting National Account information
void NationalAccount::accept( IVisitor* aVisitor, const int aPeriod ) const {
aVisitor->startVisitNationalAccount( this, aPeriod );
aVisitor->endVisitNationalAccount( this, aPeriod );
}