Skip to content

Conversation

@guptapratykshh
Copy link
Contributor

@guptapratykshh guptapratykshh commented Jan 14, 2026

Proposed Changes

This PR implements the NASA 7-coefficient polynomial model for calculating specific heat capacity (Cp) and enthalpy in incompressible ideal gas flows. This is a standard format in thermochemistry that allows for temperature-dependent properties with high accuracy across two temperature ranges.

Added:

  • New Fluid Model: Added CIncIdealGasNASA class implementing the standard NASA polynomial equations for Cp, H, and S.
  • Robust Inversion: Implemented a Newton-Raphson solver to accurately recover Temperature from Enthalpy (T(h)) with machine precision.
  • Config Integration: Updated CConfig to parse NASA coefficients (NASA_POLYCOEFFS_LOW, NASA_POLYCOEFFS_HIGH) and temperature ranges (NASA_TEMP_LOW, etc.).
  • Comprehensive Testing: Added a dedicated unit test suite (UnitTests/.../CIncIdealGasNASA_tests.cpp) verifying mathematical accuracy, smooth range transitions, and thermodynamic consistency.

Related Work

Resolves #2634 ("Cp should use NASA polynomials").

PR Checklist

  • I am submitting my contribution to the develop branch.
  • My contribution generates no new compiler warnings.
  • My contribution is commented and consistent with SU2 style.
  • I used the pre-commit hook to prevent dirty commits (User to verify).
  • I have added a test case that demonstrates my contribution.
  • I have updated appropriate documentation (Pending docs update).

@guptapratykshh guptapratykshh changed the base branch from master to develop January 14, 2026 08:32
@bigfooted
Copy link
Contributor

Note that we already have CP_POLYCOEFFS for polynomial Cp. I think it is best to just re-use this, but use CP_NASA=YES to indicate we want to use the NASA format.
Also note that the nasa polynomials are already in polynomial format, but:

  1. we need to multiply by the universal gas constant R
  2. in the nasa polynomials, Cp is the molar cp and we need mass Cp (J/kg.K).

There is no need to implement the full nasa format here (we can do that with coolprop or cantera), a user can just copy the polynomial coefficients from the database for his temperature range of interest. Just keep it simple here.

Comment on lines 41 to 43
* Cp/R = a1 + a2*T + a3*T^2 + a4*T^3 + a5*T^4
* H/(R*T) = a1 + a2*T/2 + a3*T^2/3 + a4*T^3/4 + a5*T^4/5 + a6/T
* S/R = a1*ln(T) + a2*T + a3*T^2/2 + a4*T^3/3 + a5*T^4/4 + a7
Copy link
Member

Choose a reason for hiding this comment

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

what is your reference for this? it looks incorrect

Copy link
Contributor Author

Choose a reason for hiding this comment

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

equations are correct and follow standard NASA 7-coefficient polynomial format used in CEA (Chemical Equilibrium with Applications) thermodynamic database(around pages 13-14 of the pdf)

link: https://ntrs.nasa.gov/api/citations/20020085330/downloads/20020085330.pdf

Copy link
Contributor

Choose a reason for hiding this comment

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

I think nasa-7 is fine, nasa-9 also has a T^-1 and T^-2 term for cp but most chemistry databases use nasa-7.

Copy link
Member

Choose a reason for hiding this comment

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

One is a subset of the other, I would say we should just make it handle the full thing. Users can put 0 for the coefficients they don't use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated implementation to support full NASA-9 coefficient format, which includes extra T^-1 and T^-2 terms.

@guptapratykshh guptapratykshh force-pushed the feature/nasa-polynomials-cp-2634 branch from 00e0013 to eca925a Compare January 15, 2026 17:00
Comment on lines +82 to +86
for (int i = 0; i < N_COEFFS; ++i) {
if (i < config->GetnPolyCoeffs()) {
coeffs_[i] = config->GetCp_PolyCoeff(i);
} else {
coeffs_[i] = 0.0;
Copy link
Member

Choose a reason for hiding this comment

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

Looks good.
How is nondimensionalization handled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

since NASA coefficients (a1-a9) are already dimensionless and define Cp/R directly, they don't require standard temperature-power nondimensionalization. the model simply uses these raw coefficients with nondimensional gas constant and temperature. I have verified this aligns with NASA reference documentation and confirmed it works correctly in tests.

Copy link
Member

Choose a reason for hiding this comment

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

What about the temperature we are using to evaluate the polynomial?
Perhaps you can add some regression tests for a simple airfoil, dimensional and nondimensional.
And please update the config_template with the new options.

Can we use this model for the compressible solver too?

@guptapratykshh guptapratykshh force-pushed the feature/nasa-polynomials-cp-2634 branch from 2da80c3 to 1429185 Compare January 16, 2026 05:18
@guptapratykshh guptapratykshh force-pushed the feature/nasa-polynomials-cp-2634 branch from 1429185 to 7fbbf18 Compare January 16, 2026 05:21
Copy link
Member

@pcarruscag pcarruscag left a comment

Choose a reason for hiding this comment

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

What about the regression tests?

Comment on lines 179 to 187
if (temp_iter < Temperature_Min) {
// Clamp to min but don't break immediately to allow recovery if simple overshoot
if (abs(delta_temp_iter) < toll) break;
temp_iter = Temperature_Min;
}
if (temp_iter > Temperature_Max) {
if (abs(delta_temp_iter) < toll) break;
temp_iter = Temperature_Max;
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (temp_iter < Temperature_Min) {
// Clamp to min but don't break immediately to allow recovery if simple overshoot
if (abs(delta_temp_iter) < toll) break;
temp_iter = Temperature_Min;
}
if (temp_iter > Temperature_Max) {
if (abs(delta_temp_iter) < toll) break;
temp_iter = Temperature_Max;
}
temp_iter = fmin(fmax(Temperature_Min, temp_iter), Temperature_Max);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

const su2double t_inv2 = t_inv * t_inv;

// NASA-9: Cp/R = a1*T^-2 + a2*T^-1 + a3 + a4*T + a5*T^2 + a6*T^3 + a7*T^4
su2double Cp_over_R = a1*t_inv2 + a2*t_inv + a3 + a4*T_dim + a5*T_dim*T_dim + a6*T_dim*T_dim*T_dim + a7*T_dim*T_dim*T_dim*T_dim;
Copy link
Member

Choose a reason for hiding this comment

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

Use the pow function, this is ugly and not even optimal

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

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.

Cp should use NASA polynomials

3 participants