diff --git a/README.md b/README.md
index e32bf50dc8..15e3931267 100644
--- a/README.md
+++ b/README.md
@@ -52,8 +52,9 @@ mitigation policy.
* [GCAM Documentation](http://jgcri.github.io/gcam-doc/)
* [Getting Started with GCAM](http://jgcri.github.io/gcam-doc/user-guide.html)
-* [GCAM Community](http://www.globalchange.umd.edu/models/gcam/gcam-community/)
+* [GCAM Community](https://gcims.pnnl.gov/community)
* [GCAM Videos and Tutorial Slides](https://gcims.pnnl.gov/community)
+* [GCAM Citation and Co-authorship Guidelines](http://jgcri.github.io/gcam-doc/community-guide.html)
## Selected Publications
diff --git a/cvs/objects/build/linux/config.system b/cvs/objects/build/linux/config.system
index dd96cdade3..1c3eeaac4f 100644
--- a/cvs/objects/build/linux/config.system
+++ b/cvs/objects/build/linux/config.system
@@ -17,6 +17,9 @@ TBB_INCLUDE = $(GCAMLIB_HOME)/include/oneapi
TBB_LIB = $(GCAMLIB_HOME)/lib
JAVA_INCLUDE = ${JAVA_HOME}/include
JAVA_LIB = ${JAVA_HOME}/jre/lib/amd64/server
+ifeq (openjdk,$(findstring openjdk,$(JAVA_HOME)))
+JAVA_LIB = ${JAVA_HOME}/lib/server
+endif
JARS_LIB = $(GCAMLIB_HOME)/lib/jars/*
## `module load mkl/15.0.1` will get you the following variables:
ifdef MLIB_CFLAGS
diff --git a/cvs/objects/build/linux/configure.gcam b/cvs/objects/build/linux/configure.gcam
index d10b827489..e526881a18 100644
--- a/cvs/objects/build/linux/configure.gcam
+++ b/cvs/objects/build/linux/configure.gcam
@@ -12,7 +12,7 @@ ifeq ($(strip $(CC)),)
CC = gcc
endif
CXXOPTIM = -O3 -pthread
-CXXDEBUG = -ggdb -DNDEBUG -DFUSION_MAX_VECTOR_SIZE=30
+CXXDEBUG = -ggdb -DNDEBUG
CXXBASEOPTS = $(CXXDEBUG)
ARCH_FLAGS =
@@ -123,7 +123,9 @@ ifeq ($(strip $(JARS_LIB)),)
$(error Unable to detect Jar lib path, please set env variable JARS_LIB)
endif
## custom values set by environment variables
-OSNAME_LOWERCASE := $(shell uname -s | tr '[:upper:]' '[:lower:]')
+ifndef OSNAME_LOWERCASE
+ OSNAME_LOWERCASE := $(shell uname -s | tr '[:upper:]' '[:lower:]')
+endif
JAVAINC = -I$(JAVA_INCLUDE) -I$(JAVA_INCLUDE)/$(OSNAME_LOWERCASE)
JAVALIB = -L$(JAVA_LIB)
JAVA_RPATH = -Wl,-rpath,$(JAVA_LIB)
@@ -158,7 +160,7 @@ LIBDIR = -L/usr/local/lib -L$(BUILDPATH) $(JAVALIB) $(TBB_LIBRARY)
### The rest should be mostly compiler independent
## Note $(PROF) will be set as needed if we are building the gcam-prof target
CPPFLAGS = $(INCLUDE) $(ARCH_FLAGS) $(JARSLIB) -DGCAM_PARALLEL_ENABLED=$(USE_GCAM_PARALLEL) -DUSE_HECTOR=$(USE_HECTOR) $(MKL_CFLAGS)
-CXXFLAGS = $(CXXOPTIM) $(CXXBASEOPTS) $(PROF) -MMD -std=$(CXXSTD) -Wno-deprecated
+CXXFLAGS = $(CXXOPTIM) $(CXXBASEOPTS) $(PROF) $(CXXEXTRA) -MMD -std=$(CXXSTD) -Wno-deprecated
FCFLAGS = $(FCOPTIM) $(FCBASEOPTS) $(PROF)
LD = $(CXX) $(PROF)
LDFLAGS = $(CXXFLAGS) $(JAVA_RPATH) $(TBB_RPATH) $(MKL_LDFLAGS)
diff --git a/cvs/objects/build/vc10/objects.vcxproj b/cvs/objects/build/vc10/objects.vcxproj
index 5d4ffc1cb3..c5ac94a9be 100644
--- a/cvs/objects/build/vc10/objects.vcxproj
+++ b/cvs/objects/build/vc10/objects.vcxproj
@@ -372,7 +372,7 @@
OnlyExplicitInline
true
..\..\..\..\libs\boost-lib;..\..\..\..\libs\java\include;..\..\..\..\libs\java\include\win32;..\..;..\..\climate\source\hector\headers;..\..\..\..\libs\tbb\include;..\..\..\..\libs\Eigen;%(AdditionalIncludeDirectories)
- WIN32;BOOST_DATE_TIME_NO_LIB;BOOST_IOSTREAMS_NO_LIB;FUSION_MAX_VECTOR_SIZE=30;BOOST_MATH_TR1_NO_LIB;NDEBUG;EIGEN_MPL2_ONLY;GCAM_PARALLEL_ENABLED;_WINDOWS;_AFXDLL;NOGDI;NOMINMAX;JARS_LIB#"../libs/basex/BaseX.jar\x3B../libs/jars/*";%(PreprocessorDefinitions)
+ WIN32;BOOST_DATE_TIME_NO_LIB;BOOST_IOSTREAMS_NO_LIB;BOOST_MATH_TR1_NO_LIB;NDEBUG;EIGEN_MPL2_ONLY;GCAM_PARALLEL_ENABLED;_WINDOWS;_AFXDLL;NOGDI;NOMINMAX;JARS_LIB#"../libs/basex/BaseX.jar\x3B../libs/jars/*";%(PreprocessorDefinitions)
true
MultiThreadedDLL
true
diff --git a/cvs/objects/build/xcode3/objects.xcodeproj/project.pbxproj b/cvs/objects/build/xcode3/objects.xcodeproj/project.pbxproj
index 70553b7636..168570becd 100644
--- a/cvs/objects/build/xcode3/objects.xcodeproj/project.pbxproj
+++ b/cvs/objects/build/xcode3/objects.xcodeproj/project.pbxproj
@@ -2519,7 +2519,6 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"JARS_LIB=\"\\\"../libs/basex/BaseX.jar:../libs/jars/*\\\"\"",
- "FUSION_MAX_VECTOR_SIZE=30",
);
GCC_UNROLL_LOOPS = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -2562,7 +2561,6 @@
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
"JARS_LIB=\"\\\"../libs/basex/BaseX.jar:../libs/jars/*\\\"\"",
- "FUSION_MAX_VECTOR_SIZE=30",
EIGEN_MPL2_ONLY,
BOOST_IOSTREAMS_NO_LIB,
);
diff --git a/cvs/objects/containers/include/national_account.h b/cvs/objects/containers/include/national_account.h
index df9dac8560..45c6800146 100755
--- a/cvs/objects/containers/include/national_account.h
+++ b/cvs/objects/containers/include/national_account.h
@@ -112,6 +112,7 @@ class NationalAccount: public IVisitable, public IYeared, public AParsable
INVESTMENT,
DEPRECIATION,
CAPITAL_STOCK,
+ CAPITAL_VALUE,
CAPITAL_ENERGY_INV,
CONSUMER_DURABLE_INV,
GDP,
diff --git a/cvs/objects/containers/source/national_account.cpp b/cvs/objects/containers/source/national_account.cpp
index 673d5726d6..6c2ac8fad4 100755
--- a/cvs/objects/containers/source/national_account.cpp
+++ b/cvs/objects/containers/source/national_account.cpp
@@ -109,6 +109,9 @@ bool NationalAccount::XMLParse( rapidxml::xml_node* & aNode ) {
else if ( nodeName == enumToXMLName( CAPITAL_STOCK ) ) {
setAccount( CAPITAL_STOCK, XMLParseHelper::getValue( aNode ) );
}
+ else if ( nodeName == enumToXMLName( CAPITAL_VALUE ) ) {
+ setAccount( CAPITAL_VALUE, XMLParseHelper::getValue( aNode ) );
+ }
else if ( nodeName == enumToXMLName( DEPRECIATION_RATE ) ) {
setAccount( DEPRECIATION_RATE, XMLParseHelper::getValue( aNode ) );
}
@@ -287,6 +290,7 @@ const string& NationalAccount::enumToXMLName( const AccountType aType ) const {
"investment",
"depreciation",
"capital-stock",
+ "capital-value",
"energy-investment",
"consumer-durable",
"GDP",
diff --git a/cvs/objects/containers/source/single_scenario_runner.cpp b/cvs/objects/containers/source/single_scenario_runner.cpp
index de72dcd5e7..b520824bed 100644
--- a/cvs/objects/containers/source/single_scenario_runner.cpp
+++ b/cvs/objects/containers/source/single_scenario_runner.cpp
@@ -147,7 +147,7 @@ bool SingleScenarioRunner::setupScenarios( Timer& timer,
// Add to all loggers that a new scenario is starting so that users may more
// easily parse which scenario the messages pertain to.
- LoggerFactory::logNewScenarioStarting( overrideName );
+ LoggerFactory::getInstance()->logNewScenarioStarting( overrideName );
// Print data read in time.
mainLog.setLevel( ILogger::DEBUG );
diff --git a/cvs/objects/emissions/include/aghg.h b/cvs/objects/emissions/include/aghg.h
index aa8a9a8084..a18a5f8466 100644
--- a/cvs/objects/emissions/include/aghg.h
+++ b/cvs/objects/emissions/include/aghg.h
@@ -56,13 +56,13 @@
#include "util/base/include/value.h"
#include "util/base/include/time_vector.h"
#include "util/base/include/data_definition_util.h"
+#include "marketplace/include/cached_market.h"
// Forward declarations
class IInfo;
class IOutput;
class ICaptureComponent;
class IInput;
-class CachedMarket;
// Need to forward declare the subclasses as well.
class CO2Emissions;
@@ -208,7 +208,7 @@ class AGHG: public INamed, public IVisitable, private boost::noncopyable
//! Pre-located market which has been cached from the marketplace to get the price
//! of this ghg and add demands to the market.
- std::unique_ptr mCachedMarket;
+ CachedMarket mCachedMarket;
/*!
* \brief XML debug output stream for derived classes
diff --git a/cvs/objects/emissions/source/aghg.cpp b/cvs/objects/emissions/source/aghg.cpp
index e2125f2c61..7d7529ece2 100644
--- a/cvs/objects/emissions/source/aghg.cpp
+++ b/cvs/objects/emissions/source/aghg.cpp
@@ -123,7 +123,13 @@ void AGHG::completeInit( const string& aRegionName, const string& aSectorName,
* \param aPeriod Model period.
*/
void AGHG::initCalc( const string& aRegionName, const IInfo* aLocalInfo, const int aPeriod ) {
- mCachedMarket = scenario->getMarketplace()->locateMarket( getName(), aRegionName, aPeriod );
+ // Ideally we only need to locate the market once, however during completeInit
+ // all markets may have not yet been set up. So, instead we avoid re-lookups
+ // if the market has been found. Unfortunately, this means if the market will
+ // never be found we will continue to try to look it up each model period.
+ if(!mCachedMarket.hasLocatedMarket()) {
+ mCachedMarket = scenario->getMarketplace()->locateMarket( getName(), aRegionName );
+ }
}
/*!
@@ -133,9 +139,9 @@ void AGHG::initCalc( const string& aRegionName, const IInfo* aLocalInfo, const i
*/
void AGHG::addEmissionsToMarket( const string& aRegionName, const int aPeriod ){
// set emissions as demand side of gas market
- mCachedMarket->addToDemand( getName(), aRegionName,
- mEmissions[ aPeriod ],
- aPeriod, false );
+ mCachedMarket.addToDemand( getName(), aRegionName,
+ mEmissions[ aPeriod ],
+ aPeriod, false );
}
/*! Second Method: Convert GHG tax and any storage costs into energy units using
@@ -157,7 +163,7 @@ double AGHG::getGHGValue( const IInput* aInput, const string& aRegionName,
const int aPeriod ) const
{
// Determine if there is a tax.
- double ghgTax = mCachedMarket->getPrice( getName(), aRegionName, aPeriod, false );
+ double ghgTax = mCachedMarket.getPrice( getName(), aRegionName, aPeriod, false );
if( ghgTax == Marketplace::NO_MARKET_PRICE ){
ghgTax = 0;
}
@@ -195,7 +201,7 @@ double AGHG::getGHGValue( const IOutput* aOutput, const string& aRegionName,
const int aPeriod ) const
{
// Determine if there is a tax.
- double ghgTax = mCachedMarket->getPrice( getName(), aRegionName, aPeriod, false );
+ double ghgTax = mCachedMarket.getPrice( getName(), aRegionName, aPeriod, false );
if( ghgTax == Marketplace::NO_MARKET_PRICE ){
ghgTax = 0;
}
diff --git a/cvs/objects/emissions/source/co2_emissions.cpp b/cvs/objects/emissions/source/co2_emissions.cpp
index fc58f3ce32..1b07aaa551 100644
--- a/cvs/objects/emissions/source/co2_emissions.cpp
+++ b/cvs/objects/emissions/source/co2_emissions.cpp
@@ -155,7 +155,7 @@ double CO2Emissions::getGHGValue( const std::string& aRegionName,
double removeFraction = aSequestrationDevice ? aSequestrationDevice->getRemoveFraction( getName() ) : 0;
// Get the greenhouse gas tax from the marketplace.
- double GHGTax = mCachedMarket->getPrice( getName(), aRegionName, aPeriod, false );
+ double GHGTax = mCachedMarket.getPrice( getName(), aRegionName, aPeriod, false );
if( GHGTax == Marketplace::NO_MARKET_PRICE ){
GHGTax = 0;
diff --git a/cvs/objects/emissions/source/nonco2_emissions.cpp b/cvs/objects/emissions/source/nonco2_emissions.cpp
index e48e1e75c6..9ce13d4c54 100644
--- a/cvs/objects/emissions/source/nonco2_emissions.cpp
+++ b/cvs/objects/emissions/source/nonco2_emissions.cpp
@@ -255,7 +255,7 @@ double NonCO2Emissions::getGHGValue( const string& aRegionName,
// Conversion from teragrams (Tg=MT) of X per EJ to metric tons of X per GJ
const double CVRT_Tg_per_EJ_to_Tonne_per_GJ = 1e-3;
- double GHGTax = mCachedMarket->getPrice( getName(), aRegionName, aPeriod, false );
+ double GHGTax = mCachedMarket.getPrice( getName(), aRegionName, aPeriod, false );
if( GHGTax == Marketplace::NO_MARKET_PRICE ){
return 0;
}
diff --git a/cvs/objects/functions/include/energy_input.h b/cvs/objects/functions/include/energy_input.h
index e7ad84a265..508efc8cd8 100644
--- a/cvs/objects/functions/include/energy_input.h
+++ b/cvs/objects/functions/include/energy_input.h
@@ -50,10 +50,10 @@
#include "functions/include/minicam_input.h"
#include "util/base/include/value.h"
#include "util/base/include/time_vector.h"
+#include "marketplace/include/cached_market.h"
class Tabs;
class ICoefficient;
-class CachedMarket;
/*!
* \ingroup Objects
@@ -205,7 +205,7 @@ class EnergyInput: public MiniCAMInput
//! A pre-located market which has been cahced from the marketplace to get
//! the price and add demands to.
- std::unique_ptr mCachedMarket;
+ CachedMarket mCachedMarket;
private:
const static std::string XML_REPORTING_NAME; //!< tag name for reporting xml db
diff --git a/cvs/objects/functions/source/energy_input.cpp b/cvs/objects/functions/source/energy_input.cpp
index 7d19944507..094650a91c 100644
--- a/cvs/objects/functions/source/energy_input.cpp
+++ b/cvs/objects/functions/source/energy_input.cpp
@@ -244,7 +244,13 @@ void EnergyInput::initCalc( const string& aRegionName,
mAdjustedCoefficients[ aPeriod ] = 1;
}
- mCachedMarket = scenario->getMarketplace()->locateMarket( mName, mMarketName, aPeriod );
+ // Ideally we only need to locate the market once, however during completeInit
+ // all markets may have not yet been set up. So, instead we avoid re-lookups
+ // if the market has been found. Unfortunately, this means if the market will
+ // never be found we will continue to try to look it up each model period.
+ if(!mCachedMarket.hasLocatedMarket()) {
+ mCachedMarket = scenario->getMarketplace()->locateMarket( mName, mMarketName );
+ }
}
/*! \brief Initialize the type flags.
@@ -302,9 +308,9 @@ void EnergyInput::setPhysicalDemand( double aPhysicalDemand,
const int aPeriod )
{
mPhysicalDemand[ aPeriod ].set( aPhysicalDemand );
- mCachedMarket->addToDemand( mName, mMarketName,
- mPhysicalDemand[ aPeriod ],
- aPeriod, true );
+ mCachedMarket.addToDemand( mName, mMarketName,
+ mPhysicalDemand[ aPeriod ],
+ aPeriod, true );
}
double EnergyInput::getCoefficient( const int aPeriod ) const {
@@ -328,7 +334,7 @@ double EnergyInput::getPrice( const string& aRegionName,
const int aPeriod ) const
{
return mPriceUnitConversionFactor *
- mCachedMarket->getPrice( mName, mMarketName, aPeriod );
+ mCachedMarket.getPrice( mName, mMarketName, aPeriod );
}
void EnergyInput::setPrice( const string& aRegionName,
diff --git a/cvs/objects/functions/source/food_demand_function.cpp b/cvs/objects/functions/source/food_demand_function.cpp
index ae0c039144..eacee4fd03 100644
--- a/cvs/objects/functions/source/food_demand_function.cpp
+++ b/cvs/objects/functions/source/food_demand_function.cpp
@@ -139,13 +139,6 @@ double FoodDemandFunction::calcDemand( InputSet& aInput, double income, const st
for( size_t j = 0; j < aInput.size(); ++j ) {
currDemand *= pow( adjPricesCapped[j], foodInputs[i]->calcPriceExponent( foodInputs[j], adjIncome, aRegionName, aPeriod ) );
}
- if( adjPrices[i] < adjPricesCapped[i] ) {
- // we have been sent negative prices, since we have capped prices
- // in the demand calculations above we need to apply some penalty
- // to send a signal to the solver such that the more negative a price
- // becomes, the higher the demand
- currDemand = SectorUtils::adjustDemandForNegativePrice( currDemand, adjPrices[i] );
- }
demands[i] = currDemand;
// the demand for materials is just the residual of the food demand:
// q_m = x - SUM_i(w_i * q_i)
@@ -174,6 +167,13 @@ double FoodDemandFunction::calcDemand( InputSet& aInput, double income, const st
// point, the inputs will take care of converting to Pcal / year as
// is expected in the supply sectors.
for( size_t i = 0; i < aInput.size(); ++i ) {
+ if( adjPrices[i] < adjPricesCapped[i] ) {
+ // we have been sent negative prices, since we have capped prices
+ // in the demand calculations above we need to apply some penalty
+ // to send a signal to the solver such that the more negative a price
+ // becomes, the higher the demand
+ demands[i] = SectorUtils::adjustDemandForNegativePrice( demands[i], adjPrices[i] );
+ }
foodInputs[i]->setPhysicalDemand( demands[i], aRegionName, aPeriod );
foodInputs[i]->setActualShare( alphaActual[i], aRegionName, aPeriod );
}
diff --git a/cvs/objects/functions/source/function_utils.cpp b/cvs/objects/functions/source/function_utils.cpp
index 17f5ee608a..a2fb85507e 100644
--- a/cvs/objects/functions/source/function_utils.cpp
+++ b/cvs/objects/functions/source/function_utils.cpp
@@ -128,7 +128,7 @@ double FunctionUtils::DEFLATOR_1975_PER_DEFLATOR_2005( void )
//! Function to return 1990 to 1975 US $ deflator.
double FunctionUtils::DEFLATOR_1990_PER_DEFLATOR_1975( void )
{
- return 2.212; // Ratio of 1990/1975 deflators
+ return 2.129; // Ratio of 1990/1975 deflators
}
//! Function to return kWh to GJ conversion.
diff --git a/cvs/objects/functions/source/nested_ces_production_function_macro.cpp b/cvs/objects/functions/source/nested_ces_production_function_macro.cpp
index 91dda08b97..f77b367c4c 100755
--- a/cvs/objects/functions/source/nested_ces_production_function_macro.cpp
+++ b/cvs/objects/functions/source/nested_ces_production_function_macro.cpp
@@ -318,25 +318,23 @@ double NestedCESProductionFunctionMacro::calcGrossOutput( const string& aRegionN
double grossOutput = aNationalAccount->getAccountValue(NationalAccount::GROSS_OUTPUT);
// calcualte value shares
- // Note: in principle the energy value and quantity could be different but given
- // energy the Q is just a service index weighted by prices these are indeed the same
- double energyV = energyQ;
double laborV = aNationalAccount->getAccountValue(NationalAccount::LABOR_WAGES);
+ double capitalV = aNationalAccount->getAccountValue(NationalAccount::CAPITAL_VALUE);
- double shareE = energyV / grossOutput;
+ double shareK = capitalV / grossOutput;
double shareL = laborV / grossOutput;
- double shareK = (1.0 - shareE - shareL);
+ double shareE = (1.0 - shareK - shareL);
// Given the energy value is being pulled out of GCAM without adjustment
- // there is a chance for inconsistency and send the remaining value (which is
- // all attributed to capital) to <= zero. Instead we will enforce a minimum
- // capital share and adjust both labor and energy to make up for the shortfall
- const double MIN_CAPITAL_SHARE = 0.05;
- if(shareK < MIN_CAPITAL_SHARE) {
- double shareAdj = MIN_CAPITAL_SHARE - shareK;
+ // there is a chance for inconsistency and send the remaining value to <= zero.
+ // Instead we will enforce a minimum energy share and adjust both labor and capital
+ // to make up for the shortfall
+ const double MIN_SLACK_SHARE = 0.05;
+ if(shareE < MIN_SLACK_SHARE) {
+ double shareAdj = (1.0 - MIN_SLACK_SHARE) / (shareK + shareL);
// adjust labor and energy uniformily to meet the minimum threshold
- shareE -= shareAdj / 2.0;
- shareL -= shareAdj / 2.0;
- shareK = MIN_CAPITAL_SHARE;
+ shareK *= shareAdj;
+ shareL *= shareAdj;
+ shareE = MIN_SLACK_SHARE;
}
// calibrate and store scalers
diff --git a/cvs/objects/java/source/WriteLocalBaseXDB.java b/cvs/objects/java/source/WriteLocalBaseXDB.java
index e7a8f3ef0c..493932c7f4 100644
--- a/cvs/objects/java/source/WriteLocalBaseXDB.java
+++ b/cvs/objects/java/source/WriteLocalBaseXDB.java
@@ -54,34 +54,34 @@ public class WriteLocalBaseXDB implements Runnable {
/**
* The database context needed to run commands on the DB.
*/
- private Context mContext = null;
+ protected Context mContext = null;
/**
* The thread on which writing to the DB will take place.
*/
- private final Thread mWorkerThread = new Thread( this );
+ protected final Thread mWorkerThread = new Thread( this );
/**
* The command which executes adding the XML to the database.
* We keep a reference here in case we need to cancel the
* command incase something went wrong.
*/
- private Add mAddCommand = null;
+ protected Add mAddCommand = null;
/**
* The stream that will transfer the XML read from GCAM and write it to the DB.
*/
- private final PipedInputStream mWriteToDBStream = new PipedInputStream( XMLDBDriver.BUFFER_SIZE );
+ protected final PipedInputStream mWriteToDBStream = new PipedInputStream( XMLDBDriver.BUFFER_SIZE );
/**
* The location of the database to write the XML to.
*/
- private final String mDBLocation;
+ protected final String mDBLocation;
/**
* A unique name to call the document to be added into the DB.
*/
- private final String mDocName;
+ protected final String mDocName;
/**
* Constructor which will open the DB and get ready to receive XML to put
@@ -140,7 +140,7 @@ public Context getContext() {
* attempting to write to a DB which appears to be open. A
* negative value indicates to wait indefinately.
*/
- private void openDB( final boolean aInMemoryDB, final int aOpenDBWait ) throws Exception {
+ protected void openDB( final boolean aInMemoryDB, final int aOpenDBWait ) throws Exception {
// We need to seperate the path to the DB and the container name (last name in the path)
File dbLocationFile = new File( mDBLocation ).getAbsoluteFile();
// The path may be a relative path so we must convert it to absolute here.
diff --git a/cvs/objects/java/source/WriteRemoteBaseXDB.java b/cvs/objects/java/source/WriteRemoteBaseXDB.java
new file mode 100644
index 0000000000..3b71987d80
--- /dev/null
+++ b/cvs/objects/java/source/WriteRemoteBaseXDB.java
@@ -0,0 +1,142 @@
+/*
+* 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/
+*
+*/
+
+import java.io.PipedOutputStream;
+import java.io.PipedInputStream;
+import java.io.IOException;
+import java.io.File;
+import java.net.URI;
+
+import org.basex.core.Context;
+import org.basex.core.cmd.Check;
+import org.basex.core.cmd.Add;
+import org.basex.core.StaticOptions;
+import org.basex.api.client.ClientSession;
+
+/**
+ * A helper class which gives GCAM a simple interface for adding or appending
+ * XML to a remote BaseX database. The XMLDBDriver will set up the interactions
+ * and notify when to close as results may be filtered before reaching the database
+ * and run queries after GCAM has cleaned up the Scenario.
+ * @author Pralit Patel
+ */
+public class WriteRemoteBaseXDB extends WriteLocalBaseXDB {
+
+ /**
+ * The Session connected to the remote server.
+ */
+ ClientSession mSession;
+
+ /**
+ * Constructor which will open the DB and get ready to receive XML to put
+ * into the DB.
+ * @param aDBLocation The URI location of the database to open of the format
+ * {@code basex://:@:/}
+ * @param aDocName A unique document name to use to store the XML in the DB.
+ * @param aInMemoryDB This option is ignored for remote DB as it will be controlled
+ * entirely by the server's configuration.
+ * @param aOpenDBWait This option is ignored for remote DB as it will be controlled
+ * entirely by the server's configuration.
+ */
+ public WriteRemoteBaseXDB( final String aURIStr, final String aDocName,
+ final boolean aInMemoryDB, final int aOpenDBWait ) throws Exception
+ {
+ super(aURIStr, aDocName, false, 0);
+ }
+
+ /**
+ * Opens a Client Session to the remote database. We will "Check" the database which
+ * will open it if it already exists or create a new one otherwise.
+ * @param aInMemoryDB This option is ignored for remote DB as it will be controlled
+ * entirely by the server's configuration.
+ * @param aOpenDBWait This option is ignored for remote DB as it will be controlled
+ * entirely by the server's configuration.
+ */
+ protected void openDB( final boolean aInMemoryDB, final int aOpenDBWait ) throws Exception {
+ // we are expecting the DB location to be a URI of format:
+ // basex://:@:/
+ URI xmldbURI = new URI(getDBLocation());
+
+ String auth = xmldbURI.getUserInfo();
+ String[] authSplit = auth.split(":");
+ String mUserName = authSplit[0];
+ String mPassword = authSplit[1];
+ String mHostName = xmldbURI.getHost();
+ int mPortNumber = xmldbURI.getPort();
+ String dbLocation = xmldbURI.getPath();
+
+ // establish the ClientSession
+ StaticOptions options = new StaticOptions(true);
+ options.set(StaticOptions.HOST, mHostName);
+ options.set(StaticOptions.PORT, mPortNumber);
+ options.set(StaticOptions.USER, mUserName);
+ options.set(StaticOptions.PASSWORD, mPassword);
+ mContext = new Context(options);
+ mSession = new ClientSession(mHostName, mPortNumber, mUserName, mPassword);
+
+
+ // "Check" that the DB is open in the remote session
+ mSession.execute(new Check( dbLocation ));
+ }
+
+ public void run() {
+ try {
+ // start "adding" XML data
+ mSession.add(mDocName, mWriteToDBStream);
+ }
+ catch( Exception error ) {
+ error.printStackTrace();
+ }
+ finally {
+ try {
+ mWriteToDBStream.close();
+ }
+ catch( IOException ioError ) {
+ // ignore
+ }
+ }
+ }
+ public void close() {
+ try {
+ // close the database
+ if( mContext != null ) {
+ mSession.close();
+ mSession = null;
+ mContext = null;
+ }
+ }
+ catch( Exception error ) {
+ error.printStackTrace();
+ }
+ }
+}
+
diff --git a/cvs/objects/java/source/XMLDBDriver.java b/cvs/objects/java/source/XMLDBDriver.java
index 46d74aaf76..20ae9a93a4 100644
--- a/cvs/objects/java/source/XMLDBDriver.java
+++ b/cvs/objects/java/source/XMLDBDriver.java
@@ -105,7 +105,9 @@ public XMLDBDriver( final String aDBLocation, final String aDocName ) {
// always open the database optionally in memory (off by default)
boolean inMemDB = Boolean.parseBoolean( config.getProperty( "in-memory", "false" ) );
int openDBWait = Integer.parseInt( config.getProperty( "open-db-wait", "-1" ) );
- mWriteDB = new WriteLocalBaseXDB( aDBLocation, aDocName, inMemDB, openDBWait );
+ mWriteDB = aDBLocation.startsWith("basex://") ?
+ new WriteRemoteBaseXDB( aDBLocation, aDocName, inMemDB, openDBWait ) :
+ new WriteLocalBaseXDB( aDBLocation, aDocName, inMemDB, openDBWait );
// optionally filter output using an XSLT style script (off by default)
String filterScript = config.getProperty( "filter-script", "" );
diff --git a/cvs/objects/marketplace/include/cached_market.h b/cvs/objects/marketplace/include/cached_market.h
index d039684d7e..a429b650fa 100644
--- a/cvs/objects/marketplace/include/cached_market.h
+++ b/cvs/objects/marketplace/include/cached_market.h
@@ -46,7 +46,7 @@
#include
-class Market;
+class MarketContainer;
class IInfo;
class Value;
@@ -70,8 +70,11 @@ class Value;
class CachedMarket
{
public:
- CachedMarket( const std::string& aGoodName, const std::string& aRegionName, const int aPeriod, Market* aLocatedMarket );
+ CachedMarket();
+ CachedMarket( const std::string& aGoodName, const std::string& aRegionName, MarketContainer* aLocatedMarket );
~CachedMarket();
+
+ bool hasLocatedMarket() { return mCachedMarket; }
void setPrice( const std::string& aGoodName, const std::string& aRegionName, const double aValue,
const int aPeriod, bool aMustExist = true );
@@ -103,12 +106,9 @@ class CachedMarket
//! The region name used when this market was located. Used for debugging.
const std::string mRegionName;
-
- //! The period used when this market was located. Used for debugging.
- const int mPeriod;
#endif
//! The actual market which is cached.
- Market* mCachedMarket;
+ MarketContainer* mCachedMarket;
};
#endif // _CACHED_MARKET_H_
diff --git a/cvs/objects/marketplace/include/marketplace.h b/cvs/objects/marketplace/include/marketplace.h
index 25820e9477..1525de19e7 100644
--- a/cvs/objects/marketplace/include/marketplace.h
+++ b/cvs/objects/marketplace/include/marketplace.h
@@ -182,8 +182,7 @@ class Marketplace: public IVisitable, private boost::noncopyable
IInfo* getMarketInfo( const std::string& aGoodName, const std::string& aRegionName,
const int aPeriod, const bool aMustExist );
- std::unique_ptr locateMarket( const std::string& aGoodName, const std::string& aRegionName,
- const int aPeriod ) const;
+ CachedMarket locateMarket( const std::string& aGoodName, const std::string& aRegionName ) const;
void accept( IVisitor* aVisitor, const int aPeriod ) const;
diff --git a/cvs/objects/marketplace/source/cached_market.cpp b/cvs/objects/marketplace/source/cached_market.cpp
index 35aa932e85..8c79f46cb2 100644
--- a/cvs/objects/marketplace/source/cached_market.cpp
+++ b/cvs/objects/marketplace/source/cached_market.cpp
@@ -42,6 +42,7 @@
#include "marketplace/include/cached_market.h"
#include "marketplace/include/market.h"
+#include "marketplace/include/market_container.h"
#include "util/logger/include/ilogger.h"
#include "util/base/include/util.h"
#include "marketplace/include/marketplace.h"
@@ -51,21 +52,26 @@ using namespace std;
extern Scenario* scenario;
+/*!
+ * \brief Default constructor. The cached market will be initialized as not found.
+ */
+CachedMarket::CachedMarket():mCachedMarket(0)
+{
+}
+
/*!
* \brief Constructor which takes the parameters used to locate the given market.
* \param aGoodName The good name used to locate aLocatedMarket. Stored for debugging.
- * \param aGoodName The region name used to locate aLocatedMarket. Stored for debugging.
- * \param aGoodName The period used to locate aLocatedMarket. Stored for debugging.
+ * \param aRegionName The region name used to locate aLocatedMarket. Stored for debugging.
* \param aLocatedMarket A pointer to the actual market which was located. Note that this
* parameter can be null which indicates the market was not found.
*/
-CachedMarket::CachedMarket( const string& aGoodName, const string& aRegionName, const int aPeriod,
- Market* aLocatedMarket )
+CachedMarket::CachedMarket( const string& aGoodName, const string& aRegionName,
+ MarketContainer* aLocatedMarket )
:
#ifndef NDEBUG
mGoodName( aGoodName ),
mRegionName( aRegionName ),
-mPeriod( aPeriod ),
#endif
mCachedMarket( aLocatedMarket )
{
@@ -100,11 +106,6 @@ void CachedMarket::setPrice( const string& aGoodName, const string& aRegionName,
*/
assert( aRegionName == mRegionName );
- /*!
- * \invariant The given period matches the one that was used when locating this market.
- */
- assert( aPeriod == mPeriod );
-
// Print a warning message if the new price is not a finite number.
if ( !util::isValidNumber( aValue ) ) {
ILogger& mainLog = ILogger::getLogger( "main_log" );
@@ -114,7 +115,7 @@ void CachedMarket::setPrice( const string& aGoodName, const string& aRegionName,
}
if ( mCachedMarket ) {
- mCachedMarket->setPrice( aValue );
+ mCachedMarket->getMarket( aPeriod )->setPrice( aValue );
}
else if( aMustExist ){
ILogger& mainLog = ILogger::getLogger( "main_log" );
@@ -147,11 +148,6 @@ void CachedMarket::addToSupply( const string& aGoodName, const string& aRegionNa
*/
assert( aRegionName == mRegionName );
- /*!
- * \invariant The given period matches the one that was used when locating this market.
- */
- assert( aPeriod == mPeriod );
-
// Print a warning message when adding infinity values to the supply.
if ( !util::isValidNumber( aValue ) ) {
ILogger& mainLog = ILogger::getLogger( "main_log" );
@@ -161,7 +157,7 @@ void CachedMarket::addToSupply( const string& aGoodName, const string& aRegionNa
}
if ( mCachedMarket ) {
- mCachedMarket->addToSupply( scenario->getMarketplace()->mIsDerivativeCalc ?
+ mCachedMarket->getMarket( aPeriod )->addToSupply( scenario->getMarketplace()->mIsDerivativeCalc ?
aValue.getDiff() : aValue.get() );
}
else if( aMustExist ){
@@ -209,7 +205,7 @@ void CachedMarket::addToDemand( const string& aGoodName, const string& aRegionNa
}
if ( mCachedMarket ) {
- mCachedMarket->addToDemand( scenario->getMarketplace()->mIsDerivativeCalc ?
+ mCachedMarket->getMarket( aPeriod )->addToDemand( scenario->getMarketplace()->mIsDerivativeCalc ?
aValue.getDiff() : aValue.get() );
}
else if( aMustExist ){
@@ -248,7 +244,7 @@ double CachedMarket::getPrice( const string& aGoodName, const string& aRegionNam
assert( aPeriod == mPeriod );
if( mCachedMarket ) {
- return mCachedMarket->getPrice();
+ return mCachedMarket->getMarket( aPeriod )->getPrice();
}
if( aMustExist ) {
@@ -287,7 +283,7 @@ double CachedMarket::getSupply( const string& aGoodName, const string& aRegionNa
assert( aPeriod == mPeriod );
if ( mCachedMarket ) {
- return mCachedMarket->getSupply();
+ return mCachedMarket->getMarket( aPeriod )->getSupply();
}
ILogger& mainLog = ILogger::getLogger( "main_log" );
@@ -323,7 +319,7 @@ double CachedMarket::getDemand( const string& aGoodName, const string& aRegionN
assert( aPeriod == mPeriod );
if ( mCachedMarket ) {
- return mCachedMarket->getDemand();
+ return mCachedMarket->getMarket( aPeriod )->getDemand();
}
ILogger& mainLog = ILogger::getLogger( "main_log" );
@@ -367,7 +363,7 @@ const IInfo* CachedMarket::getMarketInfo( const string& aGoodName, const string&
const IInfo* info = 0;
if ( mCachedMarket ) {
- info = mCachedMarket->getMarketInfo();
+ info = mCachedMarket->getMarket( aPeriod )->getMarketInfo();
/*! \invariant The market is required to return an information object
* that is non-null.
*/
@@ -419,7 +415,7 @@ IInfo* CachedMarket::getMarketInfo( const string& aGoodName, const string& aRegi
IInfo* info = 0;
if ( mCachedMarket ) {
- info = mCachedMarket->getMarketInfo();
+ info = mCachedMarket->getMarket( aPeriod )->getMarketInfo();
/*! \invariant The market is required to return an information object
* that is non-null.
*/
diff --git a/cvs/objects/marketplace/source/marketplace.cpp b/cvs/objects/marketplace/source/marketplace.cpp
index 98a98cbc8a..0c13a909da 100644
--- a/cvs/objects/marketplace/source/marketplace.cpp
+++ b/cvs/objects/marketplace/source/marketplace.cpp
@@ -850,18 +850,16 @@ IInfo* Marketplace::getMarketInfo( const string& aGoodName, const string& aRegio
* same behavior as the equivalent method in this class.
* \param aGoodName The good of the market to locate.
* \param aRegionName The region of the market to locate.
- * \param aPeriod The period for which to locate.
* \return A CachedMarket object which wraps the requested market. This will always
* be a valid object regardless of if the market was not found.
* \see CachedMarket
*/
-unique_ptr Marketplace::locateMarket( const string& aGoodName, const string& aRegionName,
- const int aPeriod ) const
+CachedMarket Marketplace::locateMarket( const string& aGoodName, const string& aRegionName ) const
{
const int marketNumber = mMarketLocator->getMarketNumber( aRegionName, aGoodName );
- unique_ptr locatedMarket( new CachedMarket( aGoodName, aRegionName, aPeriod,
- marketNumber != MarketLocator::MARKET_NOT_FOUND ?
- mMarkets[ marketNumber ]->getMarket( aPeriod ) : 0 ) );
+ CachedMarket locatedMarket( aGoodName, aRegionName,
+ marketNumber != MarketLocator::MARKET_NOT_FOUND ?
+ mMarkets[ marketNumber ] : 0 );
return locatedMarket;
}
diff --git a/cvs/objects/reporting/source/xml_db_outputter.cpp b/cvs/objects/reporting/source/xml_db_outputter.cpp
index 042f18b65c..9241d52637 100644
--- a/cvs/objects/reporting/source/xml_db_outputter.cpp
+++ b/cvs/objects/reporting/source/xml_db_outputter.cpp
@@ -1791,14 +1791,6 @@ void XMLDBOutputter::startVisitNationalAccount( const NationalAccount* aNational
attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::CONSUMER_DURABLE_INV);
XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
- currValue = aNationalAccount->getAccountValue( NationalAccount::GDP_PER_CAPITA );
- attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::GDP_PER_CAPITA);
- XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
-
- currValue = aNationalAccount->getAccountValue( NationalAccount::GDP_PER_CAPITA_PPP );
- attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::GDP_PER_CAPITA_PPP);
- XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
-
currValue = aNationalAccount->getAccountValue( NationalAccount::VALUE_ADDED );
attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::VALUE_ADDED);
XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
@@ -1844,7 +1836,17 @@ void XMLDBOutputter::startVisitNationalAccount( const NationalAccount* aNational
attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::LABOR_WAGES);
XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
- attrs[ "unit" ] = "mil pers";
+ // per cap values have different units
+ attrs[ "unit" ] = "thous 1990$ percap";
+ currValue = aNationalAccount->getAccountValue( NationalAccount::GDP_PER_CAPITA );
+ attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::GDP_PER_CAPITA);
+ XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
+
+ currValue = aNationalAccount->getAccountValue( NationalAccount::GDP_PER_CAPITA_PPP );
+ attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::GDP_PER_CAPITA_PPP);
+ XMLWriteElementWithAttributes( currValue, "account", mBuffer, mTabs.get(), attrs );
+
+ attrs[ "unit" ] = "thous pers";
// labor force in persons
currValue = aNationalAccount->getAccountValue( NationalAccount::LABOR_FORCE );
attrs[ "name" ] = aNationalAccount->enumToXMLName(NationalAccount::LABOR_FORCE);
diff --git a/cvs/objects/solution/solvers/source/logbroyden.cpp b/cvs/objects/solution/solvers/source/logbroyden.cpp
index 1b82e2d171..bf08ad03f5 100644
--- a/cvs/objects/solution/solvers/source/logbroyden.cpp
+++ b/cvs/objects/solution/solvers/source/logbroyden.cpp
@@ -682,9 +682,9 @@ int LogBroyden::bsolve(VecFVec &F, UBVECTOR &x, UBVECTOR &fx,
// to use fresh partial derivatives for *just* the unsolved markets as we may
// be in a situation that those markets are bouncing between vastly different
// derivatives
- // set the threshold at roughly 3% of the markets are left unsolved
+ // set the threshold at roughly 20% of the markets are left unsolved
// which is just some arbitrary threshold
- const int UNSOLVED_FULL_PARTIAL_THRESHOLD = 30;
+ const int UNSOLVED_FULL_PARTIAL_THRESHOLD = 5;
if((unsolved.size()*UNSOLVED_FULL_PARTIAL_THRESHOLD) < ncol) {
fdjac(F, xnew, fxnew, B, unsolved, true);
}
diff --git a/cvs/objects/technologies/include/primary_output.h b/cvs/objects/technologies/include/primary_output.h
index bd9de0d41d..26c5896ad6 100644
--- a/cvs/objects/technologies/include/primary_output.h
+++ b/cvs/objects/technologies/include/primary_output.h
@@ -47,11 +47,11 @@
#include
class Tabs;
-class CachedMarket;
#include "technologies/include/ioutput.h"
#include "util/base/include/value.h"
#include "util/base/include/time_vector.h"
+#include "marketplace/include/cached_market.h"
/*!
* \ingroup Objects
@@ -175,7 +175,7 @@ class PrimaryOutput : public IOutput {
)
//! A pre-located market which has been cached from the marketplace to add supply to.
- std::unique_ptr mCachedMarket;
+ CachedMarket mCachedMarket;
void copy( const PrimaryOutput& aOther );
};
diff --git a/cvs/objects/technologies/source/ag_storage_technology.cpp b/cvs/objects/technologies/source/ag_storage_technology.cpp
index c03d1059b9..f80fb93e6c 100644
--- a/cvs/objects/technologies/source/ag_storage_technology.cpp
+++ b/cvs/objects/technologies/source/ag_storage_technology.cpp
@@ -103,15 +103,24 @@ void AgStorageTechnology::completeInit(const string& aRegionName,
Technology::completeInit(aRegionName, aSectorName, aSubsectorName, aSubsectorInfo, aLandAllocator);
- // The AgStorageTechnology should not have any vintaging. All vintaging should be
- // in the associated pass-through sector
+ // AgStorageTechnology should have a lifetime just long enough to last two model periods, double
+ // check that now
const Modeltime* modeltime = scenario->getModeltime();
-
if (mYear < modeltime->getEndYear()) {
const int period = modeltime->getyr_to_per(mYear);
- int minLifetime = modeltime->gettimestep(period + 1); //check this
- int maxLifetime = modeltime->gettimestep(period + 1) + modeltime->gettimestep(period + 2); //check this
-
+ const int prevYear = period == 0 ?
+ (mYear - modeltime->gettimestep(period)) : modeltime->getper_to_yr(period - 1);
+ const int nextYear = (period+1) == modeltime->getmaxper() ?
+ (mYear + modeltime->gettimestep(period)) : modeltime->getper_to_yr(period+1);
+ if(mLifetimeYears != (nextYear - prevYear)) {
+ ILogger& mainLog = ILogger::getLogger("main_log");
+ mainLog.setLevel(ILogger::SEVERE);
+ mainLog << "Lifetime for " << getXMLNameStatic()
+ << " must last exatly 2 periods, instead has lifetime: "
+ << mLifetimeYears << " in " << aRegionName << ", " << aSectorName
+ << ", " << mName << " year " << mYear << endl;
+ abort();
+ }
}
}
@@ -273,9 +282,12 @@ void AgStorageTechnology::calcCost(const string& aRegionName,
const int aPeriod)
{
// we didn't want the price signal to consumption to change due to storage
- // so we need to re-inflate the price here
+ // so we need to reset it to one here
+ double origCoef = mInputs[0]->getCoefficient(aPeriod);
+ mInputs[0]->setCoefficient(1.0, aPeriod);
Technology::calcCost(aRegionName, aSectorName, aPeriod);
- mCosts[aPeriod] /= mInputs[0]->getCoefficient(aPeriod);
+ // restore the previous value in case it is needed
+ mInputs[0]->setCoefficient(origCoef, aPeriod);
}
//! write object to xml output stream
diff --git a/cvs/objects/technologies/source/primary_output.cpp b/cvs/objects/technologies/source/primary_output.cpp
index f375ee1afa..51dbf1d980 100644
--- a/cvs/objects/technologies/source/primary_output.cpp
+++ b/cvs/objects/technologies/source/primary_output.cpp
@@ -138,7 +138,13 @@ void PrimaryOutput::initCalc( const string& aRegionName,
// Initialize the cached CO2 coefficient.
mCachedCO2Coef.set( FunctionUtils::getCO2Coef( aRegionName, aSectorName, aPeriod ) );
- mCachedMarket = scenario->getMarketplace()->locateMarket( mName, aRegionName, aPeriod );
+ // Ideally we only need to locate the market once, however during completeInit
+ // all markets may have not yet been set up. So, instead we avoid re-lookups
+ // if the market has been found. Unfortunately, this means if the market will
+ // never be found we will continue to try to look it up each model period.
+ if(!mCachedMarket.hasLocatedMarket()) {
+ mCachedMarket = scenario->getMarketplace()->locateMarket( mName, aRegionName );
+ }
}
void PrimaryOutput::postCalc( const string& aRegionName,
@@ -173,7 +179,7 @@ void PrimaryOutput::setPhysicalOutput( const double aPrimaryOutput,
mPhysicalOutputs[ aPeriod ] = aPrimaryOutput;
// Add the primary output to the marketplace.
- mCachedMarket->addToSupply( mName, aRegionName, mPhysicalOutputs[ aPeriod ], aPeriod, false );
+ mCachedMarket.addToSupply( mName, aRegionName, mPhysicalOutputs[ aPeriod ], aPeriod, false );
}
double PrimaryOutput::getPhysicalOutput( const int aPeriod ) const {
@@ -193,7 +199,7 @@ double PrimaryOutput::getValue( const string& aRegionName,
}
string PrimaryOutput::getOutputUnits( const string& aRegionName ) const {
- return scenario->getMarketplace()->getMarketInfo( getName(), aRegionName, 0, true )
+ return mCachedMarket.getMarketInfo( getName(), aRegionName, 0, true )
->getString( "output-unit", false );
}
diff --git a/cvs/objects/technologies/source/production_state_factory.cpp b/cvs/objects/technologies/source/production_state_factory.cpp
index 3edfd50a3c..4a132b78bf 100644
--- a/cvs/objects/technologies/source/production_state_factory.cpp
+++ b/cvs/objects/technologies/source/production_state_factory.cpp
@@ -85,7 +85,10 @@ unique_ptr ProductionStateFactory::create( const int aInvestYe
{
// Initialize the production state.
unique_ptr newState;
- int currYear = scenario->getModeltime()->getper_to_yr( aPeriod );
+ const Modeltime* modeltime = scenario->getModeltime();
+ int currYear = modeltime->getper_to_yr( aPeriod );
+ int investPer = modeltime->getyr_to_per(aInvestYear);
+ int investTimeStep = modeltime->gettimestep(investPer);
if( aInvestYear == currYear ){
// If the new vintage has fixed output use a fixed output production
@@ -102,7 +105,7 @@ unique_ptr ProductionStateFactory::create( const int aInvestYe
}
// Check if it is a still operating vintage.
else if( ( currYear > aInvestYear ) &&
- ( aInvestYear + aLifetimeYears > currYear ) ){
+ ( (aInvestYear + aLifetimeYears - investTimeStep) >= currYear ) ){
assert( aPeriod > 0 );
newState.reset( new VintageProductionState );
// Set the base level of output to the output in the initial investment
diff --git a/cvs/objects/technologies/source/technology.cpp b/cvs/objects/technologies/source/technology.cpp
index 07a3d639b3..cfb7a90b21 100644
--- a/cvs/objects/technologies/source/technology.cpp
+++ b/cvs/objects/technologies/source/technology.cpp
@@ -286,35 +286,6 @@ void Technology::completeInit( const string& aRegionName,
// need to acccess those TechVintageVector for any reason then they will be able to.
initTechVintageVector();
- // Check if both the original MiniCAM non-energy-input and the new input-capital
- // are in the vector. If so, eliminate the non-energy-input and use input-capital
- // only so that non-energy costs are not double accounted.
- // Does not check for fixed and variable O&M, however.
- vector::iterator iterNonEnergy = mInputs.end();
- vector::iterator iterCapital = mInputs.end();
-
- // First look for input-capital since most technologies will have non-energy-input.
- for( vector::iterator iter = mInputs.begin(); iter != mInputs.end(); ++iter ) {
- // Cannot use hasTypeFlag() as both have same type.
- if( ( *iter )->isSameType( InputCapital::getXMLNameStatic() ) ){
- iterCapital = iter;
- }
- }
- // Only look for non-energy-input iterator if input-capital iterator is found.
- if( iterCapital != mInputs.end() ){
- for( vector::iterator iter = mInputs.begin(); iter != mInputs.end(); ++iter ) {
- // Cannot use hasTypeFlag() as both have same type.
- if( ( *iter )->isSameType( NonEnergyInput::getXMLNameStatic() ) ){
- iterNonEnergy = iter;
- }
- }
- }
- // If both are found, then eliminate the orginal non-energy-input since the
- // more detailed levelized capital calculation is intended to be used.
- //if( iterNonEnergy != mInputs.end() && iterCapital != mInputs.end() ){
- // mInputs.erase( iterNonEnergy );
- //}
-
// Complete the initialization of the inputs. Pass the inputs and outputs
// the most local info object available.
const IInfo* localInfo = getTechInfo() != 0 ? getTechInfo() : mTechnologyInfo.get();
diff --git a/cvs/objects/util/base/include/gcam_fusion.hpp b/cvs/objects/util/base/include/gcam_fusion.hpp
index b81d089a2a..c27d66e69f 100644
--- a/cvs/objects/util/base/include/gcam_fusion.hpp
+++ b/cvs/objects/util/base/include/gcam_fusion.hpp
@@ -494,13 +494,13 @@ struct FilterStep {
/*!
* \brief Constructor which (potentially) sets the data name and data flag filters.
*/
- FilterStep( const std::string& aDataName, const int aDataFlag = 0 ):mDataName( aDataName ), mDataFlag( aDataFlag ), mNumDescendantSteps( 0 ), mFilterMap(), mNoFilters( true ) {}
+ FilterStep( const std::string& aDataName, const int aDataFlag = 0 ):mDataName( aDataName ), mDataFlag( aDataFlag ), mNoFilters( true ), mNumDescendantSteps( 0 ), mFilterMap() {}
/*!
* \brief Constructor which (potentially) sets the data name and an IndexFilter.
* \note The memory for aFilter will be managed by this class.
*/
- FilterStep( const std::string& aDataName, IndexFilter* aFilter ):mDataName( aDataName ), mDataFlag( 0 ), mNumDescendantSteps( 0 ), mFilterMap(), mNoFilters( false ) {
+ FilterStep( const std::string& aDataName, IndexFilter* aFilter ):mDataName( aDataName ), mDataFlag( 0 ), mNoFilters( false ), mNumDescendantSteps( 0 ), mFilterMap() {
boost::fusion::at_key( mFilterMap ) = aFilter;
}
@@ -508,7 +508,7 @@ struct FilterStep {
* \brief Constructor which (potentially) sets the data name and a NamedFilter.
* \note The memory for aFilter will be managed by this class.
*/
- FilterStep( const std::string& aDataName, NamedFilter* aFilter ):mDataName( aDataName ), mDataFlag( 0 ), mNumDescendantSteps( 0 ), mFilterMap(), mNoFilters( false ) {
+ FilterStep( const std::string& aDataName, NamedFilter* aFilter ):mDataName( aDataName ), mDataFlag( 0 ), mNoFilters( false ), mNumDescendantSteps( 0 ), mFilterMap() {
boost::fusion::at_key( mFilterMap ) = aFilter;
}
@@ -516,7 +516,7 @@ struct FilterStep {
* \brief Constructor which (potentially) sets the data name and a YearFilter.
* \note The memory for aFilter will be managed by this class.
*/
- FilterStep( const std::string& aDataName, YearFilter* aFilter ):mDataName( aDataName ), mDataFlag( 0 ), mNumDescendantSteps( 0 ), mFilterMap(), mNoFilters( false ) {
+ FilterStep( const std::string& aDataName, YearFilter* aFilter ):mDataName( aDataName ), mDataFlag( 0 ), mNoFilters( false ), mNumDescendantSteps( 0 ), mFilterMap() {
boost::fusion::at_key( mFilterMap ) = aFilter;
}
diff --git a/cvs/objects/util/base/include/version.h b/cvs/objects/util/base/include/version.h
index 91e61f25d8..77b5b7d17a 100644
--- a/cvs/objects/util/base/include/version.h
+++ b/cvs/objects/util/base/include/version.h
@@ -41,10 +41,10 @@
* NOTE: ADD 1 TO LATEST SUBVERSION REVISION NUMBER
*/
//! The latest SVN revision number for identification of the build.
-#define __REVISION_NUMBER__ "gcam-v7.0"
+#define __REVISION_NUMBER__ "gcam-v7.1"
/*****************************************************************************/
//! GCAM model version.
-#define __ObjECTS_VER__ "7.0"
+#define __ObjECTS_VER__ "7.1"
#endif // _VERSION_H_
diff --git a/cvs/objects/util/base/include/xml_parse_helper.h b/cvs/objects/util/base/include/xml_parse_helper.h
index 4f19df72bc..6b95e8bea4 100644
--- a/cvs/objects/util/base/include/xml_parse_helper.h
+++ b/cvs/objects/util/base/include/xml_parse_helper.h
@@ -50,6 +50,7 @@
#include