Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Balance energy #184

Merged
merged 15 commits into from
Dec 8, 2023
Merged

Balance energy #184

merged 15 commits into from
Dec 8, 2023

Conversation

spahrenk
Copy link
Contributor

@spahrenk spahrenk commented Nov 27, 2023

Description

  • Added a function isEnergyBalanced to test whether the net change in tank energy over one simulation step is equal to the sum of all available contributions. The code was mostly copied directly from main.cc, which had run this test, but didn't require success or report the results when running the full test suite. The extant code failed this test by 10's of J/min. Sources of energy imbalance were then sought out. Five errors in energy accounting were found:
  1. The heat-distribution for wrapped sources is not represented directly by the condensity. Instead, the condentropy formulation is used, with condensity as input, to generate a thermal function, which is then normalized. If all tank node temperatures exceed the setpoint, all components of the distribution are set to zero, which causes no heat to be added. In the zero case, this was changed to return a uniform distribution, instead.
  2. Normalization of heat distribution discarded small weights, without renormalizing, leading to energy loss. This is corrected by reevaluating the normalization constant after discarding elements, then renormalizing.
  3. The doConduction section of updateTankTemps was missing a factor of 2 in the node-to-node heat transfer calculation. There also appeared to be an error in updating via nextTankTemps_C, though this was hard to localize. The coefficient bc had incorrect units, and inspection of the same function shows that it was not actually needed (only the UA is needed). The section was significantly rearranged.
  4. Adding heat above a node was designed to keep the temperature below a limit (e.g., the setpoint), but when it is "extra" heat that is added, that limit (which is associated with a heat source) prevents all of the heat from being added. However, cse continues to tally the extra-heat added, without this feedback. To address this, a separate function addExtaHeatAboveNode is added to handle these cases.
  5. As above, a heat source can carry over heat from a previous portion of a run-step interval. But addHeat was not accumulating the sum of heat over the full step.
  • Each of these errors individually were relatively small, but the net result could be on the order of ~ 0.1%. After these changes, energy appears to be conserved within computing precision.
  • The BTU<->kJ conversion factor had precision on the order of ~0.01%. A more precise value was taken from a seemingly reliable source (documented in code).
  • A test for energy balancing has been added. It is currently only configured for a single, arbitrary, single-pass model. Other models could be added easily, if needed.
  • Unfortunately, all test reference files had to be replaced to pass regression tests. Several tests in cse will also fail.

Author Progress Checklist:

  • Open draft pull request
    • Make title clearly understandable in a standalone change log context
    • Assign yourself the issue
    • Add at least one label (enhancement, bug, or maintenance)
    • Link the issue(s) addressed by this PR (under "Development" in the sidebar menu)
  • Make code changes (if you haven't already)
  • Self-review of code
    • My code follows the style guidelines of this project
    • I have added comments to my code, particularly in hard-to-understand areas
    • I have only committed the necessary changes for this fix or feature
    • I have made corresponding changes to the documentation
    • My changes generate no new warnings
    • I have ensured that my fix is effective or that my feature works as intended by:
      • exercising the code changes in the test framework, and/or
      • manually verifying the changes (as explained in the the pull request description above)
    • My changes pass all local tests
    • My changes successfully passes CI checks
    • Add any unit test for proof and documentation.
    • Merge in main branch and address resulting conflicts and/or test failures.
  • Move pull request out of draft mode and assign reviewers
  • [] Iterate with reviewers until all changes are approved
    • Make changes in response to reviewer comments
    • Merge in main branch and address resulting conflicts and/or test failures.
    • Re-request review in GitHub

Reviewer Checklist:

  • Read the pull request description
  • Perform a code review on GitHub
  • Confirm all CI checks pass and there are no build warnings
  • Pull, build, and run automated tests locally
  • Perform manual tests of the fix or feature locally
  • Add any review comments, if applicable
  • Submit review in GitHub as either
    • Request changes, or
    • Approve
  • Iterate with author until all changes are approved

@spahrenk spahrenk marked this pull request as ready for review December 6, 2023 20:38
src/HPWH.hh Outdated
@@ -1299,18 +1319,20 @@ private:

}; // end of HeatSource class

// a few extra functions for unit converesion
#define BTUperKWH 3412.14163312794 // https://www.rapidtables.com/convert/energy/kWh_to_BTU.html
Copy link
Member

Choose a reason for hiding this comment

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

Use constexpr instead of a preprocessor definition.

src/HPWH.cc Outdated
Comment on lines 2684 to 2715
// maximum heat deliverable in this timestep
double targetT_C;
while((qAdd_kJ > 0.) && (setPointNodeNum < getNumNodes())) {
// if the whole tank is at the same temp, the target temp is the setpoint
if(setPointNodeNum == (getNumNodes() - 1)) {
targetT_C = tankTemps_C[setPointNodeNum] + qAdd_kJ / nodeCp_kJperC / (setPointNodeNum + 1 - nodeNum);
}
//otherwise the target temp is the first non-equal-temp node
else {
targetT_C = tankTemps_C[setPointNodeNum + 1];
}

double deltaT_C = targetT_C - tankTemps_C[setPointNodeNum];

//heat needed to bring all equal temp. nodes up to the temp of the next node. kJ
double qInc_kJ = nodeCp_kJperC * (setPointNodeNum + 1 - nodeNum) * deltaT_C;

//Running the rest of the time won't recover
if(qInc_kJ > qAdd_kJ) {
for(int j = nodeNum; j <= setPointNodeNum; j++) {
tankTemps_C[j] += qAdd_kJ / nodeCp_kJperC / (setPointNodeNum + 1 - nodeNum);
}
qAdd_kJ = 0.;
}
else if(qInc_kJ > 0.)
{ // temp will recover by/before end of timestep
for(int j = nodeNum; j <= setPointNodeNum; j++)
tankTemps_C[j] = targetT_C;
qAdd_kJ -= qInc_kJ;
}
setPointNodeNum++;
}
Copy link
Member

Choose a reason for hiding this comment

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

Update comments here to better explain what's happening in the loop.

@nealkruis nealkruis self-requested a review December 8, 2023 15:40
@nealkruis nealkruis merged commit 39d7bd6 into master Dec 8, 2023
2 checks passed
@nealkruis nealkruis deleted the balance-energy branch December 8, 2023 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants