Skip to content

Make generic update #227

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

Merged
merged 93 commits into from
Apr 16, 2025
Merged

Make generic update #227

merged 93 commits into from
Apr 16, 2025

Conversation

spahrenk
Copy link
Contributor

@spahrenk spahrenk commented Mar 12, 2025

Expands capability for refinement of HPWH models. Data structures for specifying model parameters to vary and figure-of-merit targets to meet have been expanded to allow greater flexibility. Currently, only COP polynomial coefficients are fully implemented as parameters, while only energy factors are fully implemented as figures-of-merit. Some simplification was introduced in this update, by inferring the condenser index from the hpwh object, rather than via manual entry. The lists of parameters and metrics are passed to the makeGeneric function in an object of type 'GenericOptions'.

Performance polynomial coefficient entries for Tier-3 and Tier-4 preset models were modified by inter/extrapolation, so that temperatures 50F, 67.46F, and 95F are used as references. This allows independent refinement of the energy factor at each of these temperatures. This method is demonstrated in a unit test added to measureMetrics.cpp.

Functions for refining COP coefficients for specific energy-factor tests E50, UEF, and E95, or the collection of all three, have been added.

Solution by the secant method was added as an alternative to least-squares refinement. The least-squares implementation here remains limited to two parameters and one metric. Secant can be used to refine one parameter to meet one metric.

@spahrenk spahrenk self-assigned this Mar 12, 2025
@spahrenk spahrenk marked this pull request as draft March 12, 2025 19:54
@spahrenk spahrenk requested a review from nealkruis March 12, 2025 20:00
@spahrenk spahrenk marked this pull request as ready for review March 13, 2025 20:55
@spahrenk
Copy link
Contributor Author

spahrenk commented Mar 13, 2025

@nealkruis I haven't found any info about inlet temperatures for E50 or E95. I see that the test30-test95 in the test folder use the temps below:
test30: Ta = 0C, Tinlet = 5C
test50: Ta = 10C, Tinlet = 10C
test70: Ta = 20C, Tinlet = 20C
test95: Ta = 35C, Tinlet = 25C

@spahrenk
Copy link
Contributor Author

spahrenk commented Mar 14, 2025

@nealkruis Seems to do fine with secant method in unit test, keeping the COP slope fixed. Let me know what else is needed.

Copy link
Member

@nealkruis nealkruis left a comment

Choose a reason for hiding this comment

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

@spahrenk this is really good work on addressing the optimization problem!

As I familiarize myself with the DOE test standard, I think there are some ways to streamline the structure of the data and functions.

Finally, there are a number of areas where names/comments can be improved to make it easier for others to understand the code.

Let me know if you have any questions!

src/HPWH.cc Outdated
Comment on lines 5721 to 5726
*standardTestOptions.outputStream << "\tFirst-Hour Rating:";
*standardTestOptions.outputStream << "\t\tVolume Drawn (L): " << firstHourRating.drawVolume_L
<< "\n";
*standardTestOptions.outputStream
<< "\t\tDesignation: " << FirstHourRating::sDesigMap[firstHourRating.desig] << "\n";

Copy link
Member

Choose a reason for hiding this comment

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

This kind of messaging should be handled through courier (send_info) or produced by the client code.

Copy link
Contributor Author

@spahrenk spahrenk Mar 14, 2025

Choose a reason for hiding this comment

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

The output is directed to a text file here, when an output file path is specified, for the plotting utility. (I replaced that with JSON in a more recent version, and would like to pass the output over a websocket or similar, but haven't figured that out yet.) This was mostly a test feature, so I can definitely direct the output here to courier, rather than the console, when an output file path is not specified.

Comment on lines 309 to 313
struct HPWH::GenericOptions
{
std::vector<HPWH::Fitter::MeritInput*> meritInputs;
std::vector<HPWH::Fitter::ParamInput*> paramInputs;
};
Copy link
Member

Choose a reason for hiding this comment

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

Please follow our guidelines and use comments/names to make it easier for me to understand what this struct contains and how it is used. I already mentioned that I don't like "GenericOptions" because it is very vague. Would "FittingParameters" be a more accurate and descriptive name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These have been removed.

/** Optimizer for varying model parameters to match metrics, used by
* make_generic to implement a target UEF. The structure is fairly general, but
* currently limited to one figure-of-merit (UEF) and two parameters (COP coeffs).
* This could be expanded to include other FOMs, such as total energy in 24-h test.
Copy link
Member

Choose a reason for hiding this comment

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

Avoid using acronyms, especially when they aren't defined. FOM = figure-of-merit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, the structure needs some polishing, too.

src/HPWH.hh Outdated
Comment on lines 1139 to 1142

bool overrideAmbientT = false;
double ambientT_C = 19.7;

Copy link
Member

Choose a reason for hiding this comment

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

I think we need to reconfigure CustomTestOptions and StandardTestOptions into a "TestConfiguration" that holds:

  • Ambient Temperature
  • Inlet Temperature

We can then create some static instances of this for the UEF, E50, and E90 tests.

Some options don't ever seem to change, and I don't think we need to include them as something people calling the function can change:

  • Setpoint Temperature is always 51.7C
  • Change Setpoint? is always false
  • Number of Test Thermocouples is always 6

We may still want a separate set of settings that control test output, but really all the file output options should be handled by client code (not in the library itself).

There might be good reasons for the structures that I'm missing, but they don't feel intuitive to me.

src/HPWH.hh Outdated
Comment on lines 1149 to 1151
void makeGenericUEF(double targetEF, double ambientT_C = 19.7);
void makeGenericE50(double targetEF) { return makeGenericUEF(targetEF, 10.); }
void makeGenericE95(double targetEF) { return makeGenericUEF(targetEF, 35.); }
Copy link
Member

Choose a reason for hiding this comment

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

per comment above, I think we can change these so that they use the static "TestConfiguration"s I described above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.

src/HPWH.cc Outdated
Comment on lines 4955 to 4957
const double ambientT_C = (customTestOptions.overrideAmbientT)
? customTestOptions.ambientT_C
: 19.7; // EERE-2019-BT-TP-0032-0058, p. 40435
Copy link
Member

Choose a reason for hiding this comment

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

Pull from "TestConfiguration" instead (see comment below).

src/HPWH.cc Outdated
? customTestOptions.ambientT_C
: 19.7; // EERE-2019-BT-TP-0032-0058, p. 40435
const double externalT_C = ambientT_C;
double inletT_C = findInletT_C(ambientT_C);
Copy link
Member

Choose a reason for hiding this comment

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

Pull from "TestConfiguration" instead (see comment below).

src/HPWH.cc Outdated
Comment on lines 5204 to 5206
const double ambientT_C = (customTestOptions.overrideAmbientT)
? customTestOptions.ambientT_C
: 19.7; // EERE-2019-BT-TP-0032-0058, p. 40435
Copy link
Member

Choose a reason for hiding this comment

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

Pull from "TestConfiguration" instead (see comment below).

src/HPWH.cc Outdated
? customTestOptions.ambientT_C
: 19.7; // EERE-2019-BT-TP-0032-0058, p. 40435
const double externalT_C = ambientT_C;
double inletT_C = findInletT_C(ambientT_C);
Copy link
Member

Choose a reason for hiding this comment

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

Pull from "TestConfiguration" instead (see comment below).

src/HPWH.cc Outdated
Comment on lines 5035 to 5039
const double ambientT_C = (customTestOptions.overrideAmbientT)
? customTestOptions.ambientT_C
: 19.7; // EERE-2019-BT-TP-0032-0058, p. 40435
const double externalT_C = ambientT_C;
double inletT_C = findInletT_C(ambientT_C);
Copy link
Member

Choose a reason for hiding this comment

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

The First Hour Rating is always performed at 67.5F ambient and 58F inlet temperatures. It should be run independently of the 24 hour test, and the 24 hour test should take the first hour rating draw designation as an input.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is very useful, thx.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nealkruis
-Changed parameter names.
-Defined TestConfiguration. Declared static instances.
-Improved comments.
-Improved fit initialization.
-Use UEF temps for first-hour rating.
-Reported output with courier.

src/HPWH.cc Outdated
Comment on lines 5012 to 5021
double maxAllowedSetpointT_C;
std::string why;
if (isNewSetpointPossible(HPWH::testSetpointT_C, maxAllowedSetpointT_C, why, UNITS_C))
{
setSetpoint(testOptions.setpointT_C, UNITS_C);
setSetpoint(HPWH::testSetpointT_C);
}
else
{
if (isNewSetpointPossible(maxAllowedSetpointT_C, maxAllowedSetpointT_C, why, UNITS_C))
setSetpoint(maxAllowedSetpointT_C);
Copy link
Member

Choose a reason for hiding this comment

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

I like that you're leveraging an existing function here, though there are some specters here that make it hard to understand what is happening. The design of isNewSetpointPossible isn't great, but it can be improved in a separate branch/PR.

Copy link
Contributor Author

@spahrenk spahrenk Apr 16, 2025

Choose a reason for hiding this comment

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

We just need to assign a setpoint somewhere. Rewrite the section without using the functions?

@nealkruis nealkruis merged commit e4c8d68 into main Apr 16, 2025
7 checks passed
@nealkruis nealkruis deleted the make-generic-update branch April 16, 2025 15:18
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.

4 participants