Skip to content

Add WACC module and a new realization in the MACRO module about investment inefficiencies - #2278

Closed
daymontas1 wants to merge 73 commits into
remindmodel:developfrom
daymontas1:imperfect-markets-wacc
Closed

daymontas1 wants to merge 73 commits into
remindmodel:developfrom
daymontas1:imperfect-markets-wacc

Conversation

@daymontas1

@daymontas1 daymontas1 commented Jan 29, 2026 •

Copy link
Copy Markdown
Contributor

Capital Market Modelling in REMIND.pptx
Cost_of_Capital_Documentation_v2.docx

Purpose of this PR

This PR introduces (1) a new realization in the macro module that accounts for investment losses arising from domestic capital market inefficiencies, and (2) a new module (Module 25_WACC) for calculating capital costs associated with energy-system and macroeconomic investments.

Description

Investment_Inefficiencies
The Investment_Inefficiencies realization in the macro module computes the share of new investments that is not transformed into productive capital due to financial frictions, misallocation, installation costs, or other inefficiencies. A parameter, φ, is introduced into the capital accumulation equation to represent these inefficiencies.

Specifically, φ captures the share of gross investment that successfully translates into productive capital in each region. Regional φ values are calibrated using literature-defined bounds* and empirical data on the efficiency of financial systems.

Module 25_WACC
Module 25_WACC computes, for each time period, technology-specific weighted average cost of capital (WACC)–related costs for the energy system, as well as costs associated with macroeconomic investment flows.

Energy-technology WACC costs consist of:
(i) costs associated with newly installed capacity in the current period, and
(ii) residual costs of technologies that remain in operation from previous periods.

This structure relies on the assumption that the repayment period equals the technical lifetime of each technology. Input WACC data are primarily drawn from Calcaterra et al. and are aggregated to REMIND regions using GDP-weighted averages of the countries comprising each region.

From these values, WACC mark-ups are derived and defined as the difference between the WACC of a given technology–region pair and the lowest observed WACC. The latter corresponds to natural-gas power generation in the USA and the CAZ region (Canada, Australia, and New Zealand), which serves as the risk-free reference case (i.e., zero mark-up) against which all other combinations are benchmarked.

To preserve budget neutrality, WACC-related costs are recycled back into the economy. At the same time, to capture the stimulating effect of WACC costs on investment decisions, WACC costs calculated in the previous model iteration are deducted from those computed in the current iteration. As the model converges, the net WACC cost component in the budget constraint approaches zero.

Further documentation is provided in the attached presentation and Word file.
 

Parts concerned

  • ◻️ GAMS Code
  • ◻️ R-scripts
  • ◻️ Documentation (GAMS incode documentation, comments, tutorials)
  • ◻️ Input data / CES parameters
  • ◻️ Tests, CI/CD (continuous integration/deployment)
  • ◻️ Configuration (switches in main.gms, default.cfg, and scenario_config*.csv files)
  • ◻️ Other (please give a description)

Impact

  • ◻️ Bug fix
  • ◻️ Refactoring
  • ◻️ New feature
  • ◻️ Change of parameter values or input data (including CES parameters)
  • ◻️ Minor change (default scenarios show only small differences)
  • ◻️ Fundamental change of results of default scenarios

Checklist

Do not delete any line. Leave unfinished elements unchecked so others know how far along you are.
In the end all checkboxes must be ticked before you can merge
.

  • I executed the automated model tests (make test) after my final commit and all tests pass (FAIL 0)
  • I adjusted the reporting in remind2 if and where it was needed
  • I adjusted the madrat packages (mrremind and other packages involved) for input data generation if and where it was needed
  • My code follows the coding etiquette
  • I explained my changes within the PR, particularly in hard-to-understand areas
  • I checked that the in-code documentation is up-to-date
  • I adjusted forbiddenColumnNames in readCheckScenarioConfig.R in case the PR leads to deprecated switches
  • I updated the CHANGELOG.md correctly (added, changed, fixed, removed, input data/calibration)

Further information (optional)

  • Runs with these changes are here:
  • Comparison of results (what changes by this PR?):

@daymontas1 daymontas1 changed the title Add WACC module and a new realization in the MACRO module about inves… Add WACC module and a new realization in the MACRO module about investment inefficiencies Jan 29, 2026
@daymontas1

Copy link
Copy Markdown
Contributor Author

PR in mrremind for the required input data here: pik-piam/mrremind#778

Comment thread modules/01_macro/Investment_Inefficiencies/equations.gms Outdated

@nicobauer nicobauer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HI Diamantis. I left a few comments. Mostly they are on deletions of unnecessary lines that are commented anyways. ONly in the postsolve for the WACCS are two more important comments. Thanks and see you latter.

Comment thread modules/01_macro/Investment_Inefficiencies/equations.gms Outdated
Comment thread modules/01_macro/Investment_Inefficiencies/equations.gms Outdated
Comment thread modules/25_WACC/off/bounds.gms Outdated
Comment thread modules/25_WACC/standard/bounds.gms Outdated
Comment thread modules/25_WACC/standard/datainput.gms Outdated
Comment thread modules/25_WACC/standard/declarations.gms
Comment thread modules/25_WACC/standard/equations.gms Outdated
* WACC implementation on capital costs
***---------------------------------------------------------------------------
***This equation calculates the weighted average cost of capital (WACC) costs for new and existing technologies while ensuring that each past investment is assigned the correct WACC from the year
q25_techwaccCost(t, regi)$(t.val > 2005)..

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I see correctly that the tech-wacc parameters already include the country specific wacc parameters?

Comment thread modules/25_WACC/standard/postsolve.gms
sum((t2)$((t.val - t2.val <= pm_lifetime_max(regi,tewacc)) and (t2.val < t.val)),
(vm_costInvTeDir.l(t2, regi, tewacc)
+ vm_costInvTeAdj.l(t2, regi, tewacc)$teAdj(tewacc)
) * p25_techwacc(t2, regi, tewacc) * pm_ts(t2)/2);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /2 is the critical parameter that you wanted to x-check with Ropert Pietzcker. Right?

Comment thread core/declarations.gms Outdated
Comment thread main.gms Outdated
@daymontas1

daymontas1 commented Mar 26, 2026 •

Copy link
Copy Markdown
Contributor Author

@LaviniaBaumstark Hi Lavinia, before finalizing this PR, there is an issue we need to address. With the capital markets implementation, I face convergence issues in REMIND. I have mainly addressed these by decreasing the lifetime of macro investments.

In the previous REMIND version, I increased the limit used in the respective equation (see slide 2 in the attached presentation to this PR, equation investment lifetime) from 1% to 10%, and the model converged
(p/tmp/adamanti/remind_imperfect_markets_b/output/SSP2-NPi2025_2025-12-04_17.16.10). In the latest version, 10% did not work (p/tmp/adamanti/remind_imperfect_markets_b/output/SSP2-NPi2025_imperfectb_2026-02-20_11.40.31),
and I had to increase it even further. For example, with 50% it converged:
(p/tmp/adamanti/remind_imperfect_markets_b/output/SSP2-NPi2025_imperfectb_2026-03-19_00.01.37).

Is it possible to relax REMIND in some way so that we deal with this more fundamentally while keeping the investment lifetime at its originally planned level (in principle, 1% of the original value)? Or close to that level ? Thanks!

@LaviniaBaumstark

Copy link
Copy Markdown
Member

On Friday there was a (quick)fix for non-converging PkBudg-scenarios. I would try this. If possible, pull from develop branch

@daymontas1
daymontas1 force-pushed the imperfect-markets-wacc branch from 00e1006 to c21d420 Compare May 12, 2026 10:43
@daymontas1

Copy link
Copy Markdown
Contributor Author

PR in mrremind for the required input data here: pik-piam/mrremind#778

The mrremind PR with the input data of this REMIND PR was merged: pik-piam/mrremind#822

@nicobauer

Copy link
Copy Markdown
Contributor

I checked the calibration file for the macro-parameters. I find several gaps in the red-labeled calibrations (not for SSA, which was our bad case, but other countries). For example in the US I find this gap for late periods. We can see that the scenario wants the trajectory to decrease, but the model seems unable. This makes me wonder whether there are any lower bounds or bottlenecks that prevent the model to find a calibration that fits the benchmark data. @LaviniaBaumstark do you have any candidates? Is this encountered in other csaes as well?
image

@LaviniaBaumstark LaviniaBaumstark left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not add soo many new config files, are all needed?

@LaviniaBaumstark LaviniaBaumstark left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to merge the realization "investment_inefficiencies" together with adding "25_WACC" module?

Comment thread core/declarations.gms Outdated

vm_flexAdj(tall,all_regi,all_te) "flexibility mark-up cost or subsidy, used to emulate price changes of technologies which see lower-than-average or higher-than-average electricity prices due to more or less flexible operation[T$/TWa]"

vm_waccCost(ttot,all_regi) "difference between WACC costs in current and previous iteration"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this info be beprovided by the 25_WACC module? If so, the declaration should go to the module

@daymontas1 daymontas1 Jun 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember correctly, when I declared it in the 25 module a check flagged an issue, because it is an interface variable, it is used in more than one module (it also appears in the budget equation). This is why I moved it there. Now, I declare it only at this point. Should I move it to the 25_module ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, move it but keep the name

*** | Contact: remind@pik-potsdam.de
*** SOF ./modules/25_WACC/off/bounds.gms
*fix the WACC term of the budget equation equal to zero for all times
vm_waccCost.fx(t, regi) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add the declariation of vm_waccCost to the 25_WACC module

Comment thread modules/25_WACC/off/bounds.gms Outdated
*** | REMIND License Exception, version 1.0 (see LICENSE file).
*** | Contact: remind@pik-potsdam.de
*** SOF ./modules/25_WACC/off/bounds.gms
*fix the WACC term of the budget equation equal to zero for all times

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please start this line with ***

Comment thread renv/activate.R
# the requested version of renv
version <- "1.1.7"
attr(version, "md5") <- NULL
attr(version, "md5") <- "dd5d60f155dadff4c88c2fc6680504b4"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not merge changes on the renv folder

Comment thread CHANGELOG.md

## [Unreleased]

- **scripts** include reporttransport/remind2 (EDGE-T/REMIND) variable harmonization. reporttransport (EDGE-T side) energy service demand is rescaled to match exactly remind2 ES/FE/Emi values for variables reported by both models

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a merge left over. Please add your changes (e.g. add new module 25_WACC) to the CHANGELOG.md

Comment thread modules/25_WACC/standard/bounds.gms Outdated
*** | Contact: remind@pik-potsdam.de
*** SOF ./modules/25_WACC/standard/bounds.gms
*fix budget equation term to zero for 2005
***vm_waccCost.fx("2005",regi) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete these out-commented line

) - p25_techwaccCostO(t, regi);

***This equation calculates the capital costs for macroeconomic investments, including those coming from previous periods that are within their lifetime
q25_invwaccCost(t, regi)$(t.val > 2005) ..

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you do not need to add $(t.val > 2005) if you use t in the equation

***---------------------------------------------------------------------------
*' Calculation of total WACC costs
***---------------------------------------------------------------------------
p25_waccCostO_tewacc(t, regi, tewacc) =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to recalculate this also for fixed time periods?

Comment thread modules/25_WACC/standard/postsolve.gms Outdated

p25_techwaccCostO(t, regi) = sum(tewacc, p25_waccCostO_tewacc(t, regi, tewacc));

*** EOF ./modules/25_WACC/standard/postsolve.gms

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this line

*** | REMIND License Exception, version 1.0 (see LICENSE file).
*** | Contact: remind@pik-potsdam.de
*** SOF ./modules/25_WACC/standard/presolve.gms

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this file is empty, delete it

Comment thread modules/25_WACC/standard/sets.gms Outdated
*** | Contact: remind@pik-potsdam.de
*** SOF ./modules/25_WACC/standard/sets.gms

*** No new sets are directly related to this module.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand this sentence as you are adding a set

@daymontas1

Copy link
Copy Markdown
Contributor Author

Do we need to merge the realization "investment_inefficiencies" together with adding "25_WACC" module?

They are independent, so we don't have to. However, that would require creating a new branch where I remove the investment inefficiencies realization and commit only the changes in module 25. Is there an easier way to do this?

In any case, this new realization does not affect the standard realization in the macro module, and the corresponding mrremind data have already been merged. Based on these, how should I proceed?

@daymontas1

Copy link
Copy Markdown
Contributor Author

please do not add soo many new config files, are all needed?

No, I can remove them.

@LaviniaBaumstark

Copy link
Copy Markdown
Member

Do we need to merge the realization "investment_inefficiencies" together with adding "25_WACC" module?

They are independent, so we don't have to. However, that would require creating a new branch where I remove the investment inefficiencies realization and commit only the changes in module 25. Is there an easier way to do this?

In any case, this new realization does not affect the standard realization in the macro module, and the corresponding mrremind data have already been merged. Based on these, how should I proceed?

In general, I would prefer having seperate PRs for different features

@daymontas1

Copy link
Copy Markdown
Contributor Author

Do we need to merge the realization "investment_inefficiencies" together with adding "25_WACC" module?

They are independent, so we don't have to. However, that would require creating a new branch where I remove the investment inefficiencies realization and commit only the changes in module 25. Is there an easier way to do this?
In any case, this new realization does not affect the standard realization in the macro module, and the corresponding mrremind data have already been merged. Based on these, how should I proceed?

In general, I would prefer having seperate PRs for different features

Ok, I will split them.

@daymontas1

Copy link
Copy Markdown
Contributor Author

Closing this in favor of PR #2378 (PR for investment inefficiencies will follow).

@daymontas1 daymontas1 closed this Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants