Repository: NREL/OpenStudio (language: python)

Issue:
WaterToAirHeatPumpEquationFit curves do not support Table:Lookup
Issue overview
--------------
CoilCoolingWaterToAirHeatPumpEquationFit and CoilHeatingWaterToAirHeatPumpEquationFit do not support specifying curve data using Table:Lookup.

They are supposed to accept \reference QuadvariateFunctions but the documentation shows only that Curve:QuadLinear and Curve:QuintLinear are allowed for their respective curve fields

### Recreate the issue - see attached script

### Context
This is needed for ComStock GSHP measure development
[coil_bug.rb.txt](https://github.com/NREL/OpenStudio/files/12443495/coil_bug.rb.txt)


WaterToAirHeatPumpEquationFit curves do not support Table:Lookup
Issue overview
--------------
CoilCoolingWaterToAirHeatPumpEquationFit and CoilHeatingWaterToAirHeatPumpEquationFit do not support specifying curve data using Table:Lookup.

They are supposed to accept \reference QuadvariateFunctions but the documentation shows only that Curve:QuadLinear and Curve:QuintLinear are allowed for their respective curve fields

### Recreate the issue - see attached script

### Context
This is needed for ComStock GSHP measure development
[coil_bug.rb.txt](https://github.com/NREL/OpenStudio/files/12443495/coil_bug.rb.txt)




Discussion / hints:
Perhaps `bool setTotalCoolingCapacityCurve(const CurveQuadLinear& totalCoolingCapacityCurve);` needs to be relaxed to something like `bool setTotalCoolingCapacityCurve(const Curve& totalCoolingCapacityCurve);`?

Probably need to inventory all objects where curve type is too exclusive.
This issue is probably a lot like https://github.com/NREL/OpenStudio/issues/4611.
Perhaps `bool setTotalCoolingCapacityCurve(const CurveQuadLinear& totalCoolingCapacityCurve);` needs to be relaxed to something like `bool setTotalCoolingCapacityCurve(const Curve& totalCoolingCapacityCurve);`?

Probably need to inventory all objects where curve type is too exclusive.
This issue is probably a lot like https://github.com/NREL/OpenStudio/issues/4611.

Fix patch:
diff --git a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md
index 0d145e891d7..45b7975013c 100644
--- a/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md
+++ b/developer/doc/ReleaseNotes/OpenStudio_Release_Notes_3_7_0_TDB.md
@@ -82,6 +82,8 @@ You can also refer to the [OpenStudio SDK Python Binding Version Compatibility M
     * Fix #4930 - Support undisturbed ground temperature models on GroundHeatExchangerVertical
     * Update `GroundHeatExchanger:Vertical` to actually use the Ground Temeprature Model field
 * [#4923](https://github.com/NREL/OpenStudio/pull/4923) - Fix #4692 - Modify `Model::load` to use the VersionTranslator instead of loading it assuming the version of the loaded OSM is the same as the current SDK version being used.
+* [#4950](https://github.com/NREL/OpenStudio/pull/4950) - Addresses #4946, allow Table:Lookup curves for Coil:*:WaterToAirHeatPumpEquationFit objects
+    * `Coil:Cooling:WaterToAirHeatPumpEquationFit` and `Coil:Heating:WaterToAirHeatPumpEquationFit` have a few API-breaking changes related to its Curves. The types for the constructor, getters, and setters used to be explicit (e.g., `CurveQuadLinear`); it is now the base class, more generic, `Curve` type for added flexibility.
 
 ## Minor changes and bug fixes
 
diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateCoilCoolingWaterToAirHeatPumpEquationFit.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateCoilCoolingWaterToAirHeatPumpEquationFit.cpp
index c3e4c731859..f4a7631921d 100644
--- a/src/energyplus/ForwardTranslator/ForwardTranslateCoilCoolingWaterToAirHeatPumpEquationFit.cpp
+++ b/src/energyplus/ForwardTranslator/ForwardTranslateCoilCoolingWaterToAirHeatPumpEquationFit.cpp
@@ -11,8 +11,7 @@
 #include "../../model/Node_Impl.hpp"
 #include "../../model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp"
 #include "../../model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp"
-#include "../../model/CurveQuadLinear.hpp"
-#include "../../model/CurveQuintLinear.hpp"
+#include "../../model/Curve.hpp"
 
 #include "../../utilities/core/Logger.hpp"
 #include "../../utilities/core/Assert.hpp"
diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingWaterToAirHeatPumpEquationFit.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingWaterToAirHeatPumpEquationFit.cpp
index 2d796a8b2c9..6f65935223f 100644
--- a/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingWaterToAirHeatPumpEquationFit.cpp
+++ b/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingWaterToAirHeatPumpEquationFit.cpp
@@ -11,7 +11,7 @@
 #include "../../model/Node_Impl.hpp"
 #include "../../model/CoilHeatingWaterToAirHeatPumpEquationFit.hpp"
 #include "../../model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp"
-#include "../../model/CurveQuadLinear.hpp"
+#include "../../model/Curve.hpp"
 
 #include "../../utilities/core/Logger.hpp"
 #include "../../utilities/core/Assert.hpp"
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp
index a1b44bcbc0b..6deb6ffa090 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.cpp
@@ -19,6 +19,8 @@
 #include "CurveQuadLinear_Impl.hpp"
 #include "CurveQuintLinear.hpp"
 #include "CurveQuintLinear_Impl.hpp"
+#include "Curve.hpp"
+#include "Curve_Impl.hpp"
 
 #include <utilities/idd/OS_Coil_Cooling_WaterToAirHeatPump_EquationFit_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
@@ -184,34 +186,34 @@ namespace model {
       return value.get();
     }
 
-    CurveQuadLinear CoilCoolingWaterToAirHeatPumpEquationFit_Impl::totalCoolingCapacityCurve() const {
+    Curve CoilCoolingWaterToAirHeatPumpEquationFit_Impl::totalCoolingCapacityCurve() const {
       WorkspaceObject wo = getTarget(OS_Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCurveName).get();
-      return wo.cast<CurveQuadLinear>();
+      return wo.cast<Curve>();
     }
 
-    CurveQuintLinear CoilCoolingWaterToAirHeatPumpEquationFit_Impl::sensibleCoolingCapacityCurve() const {
+    Curve CoilCoolingWaterToAirHeatPumpEquationFit_Impl::sensibleCoolingCapacityCurve() const {
       WorkspaceObject wo = getTarget(OS_Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCurveName).get();
-      return wo.cast<CurveQuintLinear>();
+      return wo.cast<Curve>();
     }
 
-    CurveQuadLinear CoilCoolingWaterToAirHeatPumpEquationFit_Impl::coolingPowerConsumptionCurve() const {
+    Curve CoilCoolingWaterToAirHeatPumpEquationFit_Impl::coolingPowerConsumptionCurve() const {
       WorkspaceObject wo = getTarget(OS_Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCurveName).get();
-      return wo.cast<CurveQuadLinear>();
+      return wo.cast<Curve>();
     }
 
-    bool CoilCoolingWaterToAirHeatPumpEquationFit_Impl::setTotalCoolingCapacityCurve(const CurveQuadLinear& totalCoolingCapacityCurve) {
+    bool CoilCoolingWaterToAirHeatPumpEquationFit_Impl::setTotalCoolingCapacityCurve(const Curve& totalCoolingCapacityCurve) {
       bool result =
         setPointer(OS_Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCurveName, totalCoolingCapacityCurve.handle());
       return result;
     }
 
-    bool CoilCoolingWaterToAirHeatPumpEquationFit_Impl::setSensibleCoolingCapacityCurve(const CurveQuintLinear& sensibleCoolingCapacityCurve) {
+    bool CoilCoolingWaterToAirHeatPumpEquationFit_Impl::setSensibleCoolingCapacityCurve(const Curve& sensibleCoolingCapacityCurve) {
       bool result =
         setPointer(OS_Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCurveName, sensibleCoolingCapacityCurve.handle());
       return result;
     }
 
-    bool CoilCoolingWaterToAirHeatPumpEquationFit_Impl::setCoolingPowerConsumptionCurve(const CurveQuadLinear& coolingPowerConsumptionCurve) {
+    bool CoilCoolingWaterToAirHeatPumpEquationFit_Impl::setCoolingPowerConsumptionCurve(const Curve& coolingPowerConsumptionCurve) {
       bool result =
         setPointer(OS_Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCurveName, coolingPowerConsumptionCurve.handle());
       return result;
@@ -492,10 +494,9 @@ namespace model {
   }  // namespace detail
 
   // Ctors
-  CoilCoolingWaterToAirHeatPumpEquationFit::CoilCoolingWaterToAirHeatPumpEquationFit(const Model& model,
-                                                                                     const CurveQuadLinear& totalCoolingCapacityCurve,
-                                                                                     const CurveQuintLinear& sensibleCoolingCapacityCurve,
-                                                                                     const CurveQuadLinear& coolingPowerConsumptionCurve)
+  CoilCoolingWaterToAirHeatPumpEquationFit::CoilCoolingWaterToAirHeatPumpEquationFit(const Model& model, const Curve& totalCoolingCapacityCurve,
+                                                                                     const Curve& sensibleCoolingCapacityCurve,
+                                                                                     const Curve& coolingPowerConsumptionCurve)
     : WaterToAirComponent(CoilCoolingWaterToAirHeatPumpEquationFit::iddObjectType(), model) {
     OS_ASSERT(getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>());
 
@@ -752,27 +753,27 @@ namespace model {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->autosizedRatedSensibleCoolingCapacity();
   }
 
-  CurveQuadLinear CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve() const {
+  Curve CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve() const {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
   }
 
-  CurveQuintLinear CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve() const {
+  Curve CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve() const {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
   }
 
-  CurveQuadLinear CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve() const {
+  Curve CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve() const {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
   }
 
-  bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCurve(const CurveQuadLinear& totalCoolingCapacityCurve) {
+  bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCurve(const Curve& totalCoolingCapacityCurve) {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->setTotalCoolingCapacityCurve(totalCoolingCapacityCurve);
   }
 
-  bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCurve(const CurveQuintLinear& sensibleCoolingCapacityCurve) {
+  bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCurve(const Curve& sensibleCoolingCapacityCurve) {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->setSensibleCoolingCapacityCurve(sensibleCoolingCapacityCurve);
   }
 
-  bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCurve(const CurveQuadLinear& coolingPowerConsumptionCurve) {
+  bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCurve(const Curve& coolingPowerConsumptionCurve) {
     return getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->setCoolingPowerConsumptionCurve(coolingPowerConsumptionCurve);
   }
 
@@ -785,199 +786,231 @@ namespace model {
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCoefficient1() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().coefficient1Constant() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.coefficient1Constant();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient1Constant();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCoefficient1(double totalCoolingCapacityCoefficient1) {
     DEPRECATED_AT_MSG(3, 2, 0,
                       "Use "
                       "CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().setCoefficient1Constant(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.setCoefficient1Constant(totalCoolingCapacityCoefficient1);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient1Constant(totalCoolingCapacityCoefficient1);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCoefficient2() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().coefficient2w() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.coefficient2w();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient2w();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCoefficient2(double totalCoolingCapacityCoefficient2) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().setCoefficient2w(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.setCoefficient2w(totalCoolingCapacityCoefficient2);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient2w(totalCoolingCapacityCoefficient2);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCoefficient3() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().coefficient3x() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.coefficient3x();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient3x();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCoefficient3(double totalCoolingCapacityCoefficient3) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().setCoefficient3x(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.setCoefficient3x(totalCoolingCapacityCoefficient3);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient3x(totalCoolingCapacityCoefficient3);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCoefficient4() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().coefficient4y() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.coefficient4y();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient4y();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCoefficient4(double totalCoolingCapacityCoefficient4) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().setCoefficient4y(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.setCoefficient4y(totalCoolingCapacityCoefficient4);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient4y(totalCoolingCapacityCoefficient4);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCoefficient5() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().coefficient5z() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.coefficient5z();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient5z();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setTotalCoolingCapacityCoefficient5(double totalCoolingCapacityCoefficient5) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::totalCoolingCapacityCurve().setCoefficient5z(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
-    return curve.setCoefficient5z(totalCoolingCapacityCoefficient5);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->totalCoolingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient5z(totalCoolingCapacityCoefficient5);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCoefficient1() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().coefficient1Constant() instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.coefficient1Constant();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->coefficient1Constant();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCoefficient1(double sensibleCoolingCapacityCoefficient1) {
     DEPRECATED_AT_MSG(3, 2, 0,
                       "Use "
                       "CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().setCoefficient1Constant(double) instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.setCoefficient1Constant(sensibleCoolingCapacityCoefficient1);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->setCoefficient1Constant(sensibleCoolingCapacityCoefficient1);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCoefficient2() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().coefficient2v() instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.coefficient2v();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->coefficient2v();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCoefficient2(double sensibleCoolingCapacityCoefficient2) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().setCoefficient2v(double) instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.setCoefficient2v(sensibleCoolingCapacityCoefficient2);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->setCoefficient2v(sensibleCoolingCapacityCoefficient2);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCoefficient3() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().coefficient3w() instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.coefficient3w();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->coefficient3w();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCoefficient3(double sensibleCoolingCapacityCoefficient3) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().setCoefficient3w(double) instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.setCoefficient3w(sensibleCoolingCapacityCoefficient3);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->setCoefficient3w(sensibleCoolingCapacityCoefficient3);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCoefficient4() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().coefficient4x() instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.coefficient4x();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->coefficient4x();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCoefficient4(double sensibleCoolingCapacityCoefficient4) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().setCoefficient4x(double) instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.setCoefficient4x(sensibleCoolingCapacityCoefficient4);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->setCoefficient4x(sensibleCoolingCapacityCoefficient4);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCoefficient5() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().coefficient5y() instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.coefficient5y();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->coefficient5y();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCoefficient5(double sensibleCoolingCapacityCoefficient5) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().setCoefficient5y(double) instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.setCoefficient5y(sensibleCoolingCapacityCoefficient5);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->setCoefficient5y(sensibleCoolingCapacityCoefficient5);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCoefficient6() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().coefficient6z() instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.coefficient6z();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->coefficient6z();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setSensibleCoolingCapacityCoefficient6(double sensibleCoolingCapacityCoefficient6) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::sensibleCoolingCapacityCurve().setCoefficient6z(double) instead.");
-    CurveQuintLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
-    return curve.setCoefficient6z(sensibleCoolingCapacityCoefficient6);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->sensibleCoolingCapacityCurve();
+    boost::optional<CurveQuintLinear> curveQuintLinear = curve.optionalCast<CurveQuintLinear>();
+    return curveQuintLinear->setCoefficient6z(sensibleCoolingCapacityCoefficient6);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCoefficient1() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().coefficient1Constant() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.coefficient1Constant();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient1Constant();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCoefficient1(double coolingPowerConsumptionCoefficient1) {
     DEPRECATED_AT_MSG(3, 2, 0,
                       "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().setCoefficient1Constant(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.setCoefficient1Constant(coolingPowerConsumptionCoefficient1);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient1Constant(coolingPowerConsumptionCoefficient1);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCoefficient2() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().coefficient2w() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.coefficient2w();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient2w();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCoefficient2(double coolingPowerConsumptionCoefficient2) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().setCoefficient2w(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.setCoefficient2w(coolingPowerConsumptionCoefficient2);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient2w(coolingPowerConsumptionCoefficient2);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCoefficient3() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().coefficient3x() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.coefficient3x();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient3x();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCoefficient3(double coolingPowerConsumptionCoefficient3) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().setCoefficient3x(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.setCoefficient3x(coolingPowerConsumptionCoefficient3);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient3x(coolingPowerConsumptionCoefficient3);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCoefficient4() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().coefficient4y() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.coefficient4y();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient4y();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCoefficient4(double coolingPowerConsumptionCoefficient4) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().setCoefficient4y(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.setCoefficient4y(coolingPowerConsumptionCoefficient4);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient4y(coolingPowerConsumptionCoefficient4);
   }
 
   double CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCoefficient5() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().coefficient5z() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.coefficient5z();
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient5z();
   }
 
   bool CoilCoolingWaterToAirHeatPumpEquationFit::setCoolingPowerConsumptionCoefficient5(double coolingPowerConsumptionCoefficient5) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilCoolingWaterToAirHeatPumpEquationFit::coolingPowerConsumptionCurve().setCoefficient5z(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
-    return curve.setCoefficient5z(coolingPowerConsumptionCoefficient5);
+    Curve curve = getImpl<detail::CoilCoolingWaterToAirHeatPumpEquationFit_Impl>()->coolingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient5z(coolingPowerConsumptionCoefficient5);
   }
 
   /// @endcond
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp
index b28146696d6..2b28bfdbbe9 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp
@@ -15,8 +15,7 @@ namespace openstudio {
 
 namespace model {
 
-  class CurveQuadLinear;
-  class CurveQuintLinear;
+  class Curve;
 
   namespace detail {
     class CoilCoolingWaterToAirHeatPumpEquationFit_Impl;
@@ -29,9 +28,8 @@ namespace model {
     /** @name Constructors and Destructors */
 
     /** Constructs a new CoilCoolingWaterToAirHeatPumpEquationFit with required curve objects */
-    CoilCoolingWaterToAirHeatPumpEquationFit(const Model& model, const CurveQuadLinear& totalCoolingCapacityCurve,
-                                             const CurveQuintLinear& sensibleCoolingCapacityCurve,
-                                             const CurveQuadLinear& coolingPowerConsumptionCurve);
+    CoilCoolingWaterToAirHeatPumpEquationFit(const Model& model, const Curve& totalCoolingCapacityCurve, const Curve& sensibleCoolingCapacityCurve,
+                                             const Curve& coolingPowerConsumptionCurve);
 
     /** Constructs a new CoilCoolingWaterToAirHeatPumpEquationFit object and places it inside the model.  The coil is fully initialized with all companion objects. */
     CoilCoolingWaterToAirHeatPumpEquationFit(const Model& model);
@@ -81,7 +79,7 @@ namespace model {
 
     double ratedEnteringAirWetBulbTemperature() const;
 
-    CurveQuadLinear totalCoolingCapacityCurve() const;
+    Curve totalCoolingCapacityCurve() const;
 
     OS_DEPRECATED(3, 2, 0) double totalCoolingCapacityCoefficient1() const;
     OS_DEPRECATED(3, 2, 0) double totalCoolingCapacityCoefficient2() const;
@@ -89,7 +87,7 @@ namespace model {
     OS_DEPRECATED(3, 2, 0) double totalCoolingCapacityCoefficient4() const;
     OS_DEPRECATED(3, 2, 0) double totalCoolingCapacityCoefficient5() const;
 
-    CurveQuintLinear sensibleCoolingCapacityCurve() const;
+    Curve sensibleCoolingCapacityCurve() const;
 
     OS_DEPRECATED(3, 2, 0) double sensibleCoolingCapacityCoefficient1() const;
     OS_DEPRECATED(3, 2, 0) double sensibleCoolingCapacityCoefficient2() const;
@@ -98,7 +96,7 @@ namespace model {
     OS_DEPRECATED(3, 2, 0) double sensibleCoolingCapacityCoefficient5() const;
     OS_DEPRECATED(3, 2, 0) double sensibleCoolingCapacityCoefficient6() const;
 
-    CurveQuadLinear coolingPowerConsumptionCurve() const;
+    Curve coolingPowerConsumptionCurve() const;
 
     OS_DEPRECATED(3, 2, 0) double coolingPowerConsumptionCoefficient1() const;
     OS_DEPRECATED(3, 2, 0) double coolingPowerConsumptionCoefficient2() const;
@@ -148,7 +146,7 @@ namespace model {
 
     bool setRatedEnteringAirWetBulbTemperature(double ratedEnteringAirWetBulbTemperature);
 
-    bool setTotalCoolingCapacityCurve(const CurveQuadLinear& totalCoolingCapacityCurve);
+    bool setTotalCoolingCapacityCurve(const Curve& totalCoolingCapacityCurve);
 
     OS_DEPRECATED(3, 2, 0) bool setTotalCoolingCapacityCoefficient1(double totalCoolingCapacityCoefficient1);
     OS_DEPRECATED(3, 2, 0) bool setTotalCoolingCapacityCoefficient2(double totalCoolingCapacityCoefficient2);
@@ -156,7 +154,7 @@ namespace model {
     OS_DEPRECATED(3, 2, 0) bool setTotalCoolingCapacityCoefficient4(double totalCoolingCapacityCoefficient4);
     OS_DEPRECATED(3, 2, 0) bool setTotalCoolingCapacityCoefficient5(double totalCoolingCapacityCoefficient5);
 
-    bool setSensibleCoolingCapacityCurve(const CurveQuintLinear& sensibleCoolingCapacityCurve);
+    bool setSensibleCoolingCapacityCurve(const Curve& sensibleCoolingCapacityCurve);
 
     OS_DEPRECATED(3, 2, 0) bool setSensibleCoolingCapacityCoefficient1(double sensibleCoolingCapacityCoefficient1);
     OS_DEPRECATED(3, 2, 0) bool setSensibleCoolingCapacityCoefficient2(double sensibleCoolingCapacityCoefficient2);
@@ -165,7 +163,7 @@ namespace model {
     OS_DEPRECATED(3, 2, 0) bool setSensibleCoolingCapacityCoefficient5(double sensibleCoolingCapacityCoefficient5);
     OS_DEPRECATED(3, 2, 0) bool setSensibleCoolingCapacityCoefficient6(double sensibleCoolingCapacityCoefficient6);
 
-    bool setCoolingPowerConsumptionCurve(const CurveQuadLinear& coolingPowerConsumptionCurve);
+    bool setCoolingPowerConsumptionCurve(const Curve& coolingPowerConsumptionCurve);
 
     OS_DEPRECATED(3, 2, 0) bool setCoolingPowerConsumptionCoefficient1(double coolingPowerConsumptionCoefficient1);
     OS_DEPRECATED(3, 2, 0) bool setCoolingPowerConsumptionCoefficient2(double coolingPowerConsumptionCoefficient2);
diff --git a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp
index 85d53ebbe76..4798c3dba4e 100644
--- a/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp
+++ b/src/model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp
@@ -12,8 +12,7 @@
 namespace openstudio {
 namespace model {
 
-  class CurveQuadLinear;
-  class CurveQuintLinear;
+  class Curve;
 
   namespace detail {
 
@@ -98,11 +97,11 @@ namespace model {
 
       double ratedEnteringAirWetBulbTemperature() const;
 
-      CurveQuadLinear totalCoolingCapacityCurve() const;
+      Curve totalCoolingCapacityCurve() const;
 
-      CurveQuintLinear sensibleCoolingCapacityCurve() const;
+      Curve sensibleCoolingCapacityCurve() const;
 
-      CurveQuadLinear coolingPowerConsumptionCurve() const;
+      Curve coolingPowerConsumptionCurve() const;
 
       double nominalTimeforCondensateRemovaltoBegin() const;
 
@@ -160,11 +159,11 @@ namespace model {
 
       bool setRatedEnteringAirWetBulbTemperature(double ratedEnteringAirWetBulbTemperature);
 
-      bool setTotalCoolingCapacityCurve(const CurveQuadLinear& totalCoolingCapacityCurve);
+      bool setTotalCoolingCapacityCurve(const Curve& totalCoolingCapacityCurve);
 
-      bool setSensibleCoolingCapacityCurve(const CurveQuintLinear& sensibleCoolingCapacityCurve);
+      bool setSensibleCoolingCapacityCurve(const Curve& sensibleCoolingCapacityCurve);
 
-      bool setCoolingPowerConsumptionCurve(const CurveQuadLinear& coolingPowerConsumptionCurve);
+      bool setCoolingPowerConsumptionCurve(const Curve& coolingPowerConsumptionCurve);
 
       bool setNominalTimeforCondensateRemovaltoBegin(double nominalTimeforCondensateRemovaltoBegin);
 
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp
index 4ab5cb074cf..32d008473e8 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.cpp
@@ -16,6 +16,8 @@
 #include "Model.hpp"
 #include "CurveQuadLinear.hpp"
 #include "CurveQuadLinear_Impl.hpp"
+#include "Curve.hpp"
+#include "Curve_Impl.hpp"
 
 #include <utilities/idd/OS_Coil_Heating_WaterToAirHeatPump_EquationFit_FieldEnums.hxx>
 #include <utilities/idd/IddEnums.hxx>
@@ -304,22 +306,22 @@ namespace model {
       return boost::none;
     }
 
-    CurveQuadLinear CoilHeatingWaterToAirHeatPumpEquationFit_Impl::heatingCapacityCurve() const {
+    Curve CoilHeatingWaterToAirHeatPumpEquationFit_Impl::heatingCapacityCurve() const {
       WorkspaceObject wo = getTarget(OS_Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCurveName).get();
-      return wo.cast<CurveQuadLinear>();
+      return wo.cast<Curve>();
     }
 
-    bool CoilHeatingWaterToAirHeatPumpEquationFit_Impl::setHeatingCapacityCurve(const CurveQuadLinear& heatingCapacityCurve) {
+    bool CoilHeatingWaterToAirHeatPumpEquationFit_Impl::setHeatingCapacityCurve(const Curve& heatingCapacityCurve) {
       bool result = setPointer(OS_Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCurveName, heatingCapacityCurve.handle());
       return result;
     }
 
-    CurveQuadLinear CoilHeatingWaterToAirHeatPumpEquationFit_Impl::heatingPowerConsumptionCurve() const {
+    Curve CoilHeatingWaterToAirHeatPumpEquationFit_Impl::heatingPowerConsumptionCurve() const {
       WorkspaceObject wo = getTarget(OS_Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCurveName).get();
-      return wo.cast<CurveQuadLinear>();
+      return wo.cast<Curve>();
     }
 
-    bool CoilHeatingWaterToAirHeatPumpEquationFit_Impl::setHeatingPowerConsumptionCurve(const CurveQuadLinear& heatingPowerConsumptionCurve) {
+    bool CoilHeatingWaterToAirHeatPumpEquationFit_Impl::setHeatingPowerConsumptionCurve(const Curve& heatingPowerConsumptionCurve) {
       bool result =
         setPointer(OS_Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCurveName, heatingPowerConsumptionCurve.handle());
       return result;
@@ -397,8 +399,8 @@ namespace model {
   }  // namespace detail
 
   // create a new CoilHeatingWaterToAirHeatPumpEquationFit object in the model's workspace
-  CoilHeatingWaterToAirHeatPumpEquationFit::CoilHeatingWaterToAirHeatPumpEquationFit(const Model& model, const CurveQuadLinear& heatingCapacityCurve,
-                                                                                     const CurveQuadLinear& heatingPowerConsumptionCurve)
+  CoilHeatingWaterToAirHeatPumpEquationFit::CoilHeatingWaterToAirHeatPumpEquationFit(const Model& model, const Curve& heatingCapacityCurve,
+                                                                                     const Curve& heatingPowerConsumptionCurve)
     : WaterToAirComponent(CoilHeatingWaterToAirHeatPumpEquationFit::iddObjectType(), model) {
     OS_ASSERT(getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>());
 
@@ -596,19 +598,19 @@ namespace model {
     return getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->autosizedRatedHeatingCapacity();
   }
 
-  CurveQuadLinear CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve() const {
+  Curve CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve() const {
     return getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
   }
 
-  bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCurve(const CurveQuadLinear& heatingCapacityCurve) {
+  bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCurve(const Curve& heatingCapacityCurve) {
     return getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->setHeatingCapacityCurve(heatingCapacityCurve);
   }
 
-  CurveQuadLinear CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve() const {
+  Curve CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve() const {
     return getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
   }
 
-  bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCurve(const CurveQuadLinear& heatingPowerConsumptionCurve) {
+  bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCurve(const Curve& heatingPowerConsumptionCurve) {
     return getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->setHeatingPowerConsumptionCurve(heatingPowerConsumptionCurve);
   }
 
@@ -620,124 +622,144 @@ namespace model {
   // DEPRECATED
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCoefficient1() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().coefficient1Constant() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.coefficient1Constant();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient1Constant();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCoefficient1(double heatingCapacityCoefficient1) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().setCoefficient1Constant(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.setCoefficient1Constant(heatingCapacityCoefficient1);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient1Constant(heatingCapacityCoefficient1);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCoefficient2() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().coefficient2w() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.coefficient2w();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient2w();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCoefficient2(double heatingCapacityCoefficient2) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().setCoefficient2w(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.setCoefficient2w(heatingCapacityCoefficient2);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient2w(heatingCapacityCoefficient2);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCoefficient3() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().coefficient3x() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.coefficient3x();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient3x();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCoefficient3(double heatingCapacityCoefficient3) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().setCoefficient3x(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.setCoefficient3x(heatingCapacityCoefficient3);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient3x(heatingCapacityCoefficient3);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCoefficient4() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().coefficient4y() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.coefficient4y();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient4y();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCoefficient4(double heatingCapacityCoefficient4) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().setCoefficient4y(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.setCoefficient4y(heatingCapacityCoefficient4);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient4y(heatingCapacityCoefficient4);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCoefficient5() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().coefficient5z() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.coefficient5z();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient5z();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingCapacityCoefficient5(double heatingCapacityCoefficient5) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingCapacityCurve().setCoefficient5z(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
-    return curve.setCoefficient5z(heatingCapacityCoefficient5);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingCapacityCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient5z(heatingCapacityCoefficient5);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCoefficient1() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().coefficient1Constant() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.coefficient1Constant();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient1Constant();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCoefficient1(double heatingPowerConsumptionCoefficient1) {
     DEPRECATED_AT_MSG(3, 2, 0,
                       "Use "
                       "CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().setCoefficient1Constant(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.setCoefficient1Constant(heatingPowerConsumptionCoefficient1);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient1Constant(heatingPowerConsumptionCoefficient1);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCoefficient2() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().coefficient2w() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.coefficient2w();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient2w();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCoefficient2(double heatingPowerConsumptionCoefficient2) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().setCoefficient2w(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.setCoefficient2w(heatingPowerConsumptionCoefficient2);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient2w(heatingPowerConsumptionCoefficient2);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCoefficient3() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().coefficient3x() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.coefficient3x();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient3x();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCoefficient3(double heatingPowerConsumptionCoefficient3) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().setCoefficient3x(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.setCoefficient3x(heatingPowerConsumptionCoefficient3);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient3x(heatingPowerConsumptionCoefficient3);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCoefficient4() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().coefficient4y() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.coefficient4y();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient4y();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCoefficient4(double heatingPowerConsumptionCoefficient4) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().setCoefficient4y(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.setCoefficient4y(heatingPowerConsumptionCoefficient4);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient4y(heatingPowerConsumptionCoefficient4);
   }
 
   double CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCoefficient5() const {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().coefficient5z() instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.coefficient5z();
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->coefficient5z();
   }
 
   bool CoilHeatingWaterToAirHeatPumpEquationFit::setHeatingPowerConsumptionCoefficient5(double heatingPowerConsumptionCoefficient5) {
     DEPRECATED_AT_MSG(3, 2, 0, "Use CoilHeatingWaterToAirHeatPumpEquationFit::heatingPowerConsumptionCurve().setCoefficient5z(double) instead.");
-    CurveQuadLinear curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
-    return curve.setCoefficient5z(heatingPowerConsumptionCoefficient5);
+    Curve curve = getImpl<detail::CoilHeatingWaterToAirHeatPumpEquationFit_Impl>()->heatingPowerConsumptionCurve();
+    boost::optional<CurveQuadLinear> curveQuadLinear = curve.optionalCast<CurveQuadLinear>();
+    return curveQuadLinear->setCoefficient5z(heatingPowerConsumptionCoefficient5);
   }
 
   /// @endcond
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.hpp b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.hpp
index 2b497d34190..294a86e7ab4 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.hpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit.hpp
@@ -15,7 +15,7 @@ namespace openstudio {
 
 namespace model {
 
-  class CurveQuadLinear;
+  class Curve;
 
   namespace detail {
 
@@ -31,8 +31,7 @@ namespace model {
     //@{
 
     /** Constructs a new CoilCoolingWaterToAirHeatPumpEquationFit with required curve objects */
-    CoilHeatingWaterToAirHeatPumpEquationFit(const Model& model, const CurveQuadLinear& heatingCapacityCurve,
-                                             const CurveQuadLinear& heatingPowerConsumptionCurve);
+    CoilHeatingWaterToAirHeatPumpEquationFit(const Model& model, const Curve& heatingCapacityCurve, const Curve& heatingPowerConsumptionCurve);
 
     CoilHeatingWaterToAirHeatPumpEquationFit(const Model& model);
 
@@ -78,7 +77,7 @@ namespace model {
 
     double ratioofRatedHeatingCapacitytoRatedCoolingCapacity() const;
 
-    CurveQuadLinear heatingCapacityCurve() const;
+    Curve heatingCapacityCurve() const;
 
     OS_DEPRECATED(3, 2, 0) double heatingCapacityCoefficient1() const;
     OS_DEPRECATED(3, 2, 0) double heatingCapacityCoefficient2() const;
@@ -86,7 +85,7 @@ namespace model {
     OS_DEPRECATED(3, 2, 0) double heatingCapacityCoefficient4() const;
     OS_DEPRECATED(3, 2, 0) double heatingCapacityCoefficient5() const;
 
-    CurveQuadLinear heatingPowerConsumptionCurve() const;
+    Curve heatingPowerConsumptionCurve() const;
 
     OS_DEPRECATED(3, 2, 0) double heatingPowerConsumptionCoefficient1() const;
     OS_DEPRECATED(3, 2, 0) double heatingPowerConsumptionCoefficient2() const;
@@ -132,7 +131,7 @@ namespace model {
 
     bool setRatioofRatedHeatingCapacitytoRatedCoolingCapacity(double ratioofRatedHeatingCapacitytoRatedCoolingCapacity);
 
-    bool setHeatingCapacityCurve(const CurveQuadLinear& heatingCapacityCurve);
+    bool setHeatingCapacityCurve(const Curve& heatingCapacityCurve);
 
     OS_DEPRECATED(3, 2, 0) bool setHeatingCapacityCoefficient1(double heatingCapacityCoefficient1);
     OS_DEPRECATED(3, 2, 0) bool setHeatingCapacityCoefficient2(double heatingCapacityCoefficient2);
@@ -140,7 +139,7 @@ namespace model {
     OS_DEPRECATED(3, 2, 0) bool setHeatingCapacityCoefficient4(double heatingCapacityCoefficient4);
     OS_DEPRECATED(3, 2, 0) bool setHeatingCapacityCoefficient5(double heatingCapacityCoefficient5);
 
-    bool setHeatingPowerConsumptionCurve(const CurveQuadLinear& heatingPowerConsumptionCurve);
+    bool setHeatingPowerConsumptionCurve(const Curve& heatingPowerConsumptionCurve);
 
     OS_DEPRECATED(3, 2, 0) bool setHeatingPowerConsumptionCoefficient1(double heatingPowerConsumptionCoefficient1);
     OS_DEPRECATED(3, 2, 0) bool setHeatingPowerConsumptionCoefficient2(double heatingPowerConsumptionCoefficient2);
diff --git a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp
index e3a9eaf65ca..61907e51730 100644
--- a/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp
+++ b/src/model/CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp
@@ -12,7 +12,7 @@
 namespace openstudio {
 namespace model {
 
-  class CurveQuadLinear;
+  class Curve;
 
   namespace detail {
 
@@ -87,9 +87,9 @@ namespace model {
 
       double ratioofRatedHeatingCapacitytoRatedCoolingCapacity() const;
 
-      CurveQuadLinear heatingCapacityCurve() const;
+      Curve heatingCapacityCurve() const;
 
-      CurveQuadLinear heatingPowerConsumptionCurve() const;
+      Curve heatingPowerConsumptionCurve() const;
 
       boost::optional<double> autosizedRatedAirFlowRate() const;
 
@@ -139,9 +139,9 @@ namespace model {
 
       bool setRatioofRatedHeatingCapacitytoRatedCoolingCapacity(double ratioofRatedHeatingCapacitytoRatedCoolingCapacity);
 
-      bool setHeatingCapacityCurve(const CurveQuadLinear& heatingCapacityCurve);
+      bool setHeatingCapacityCurve(const Curve& heatingCapacityCurve);
 
-      bool setHeatingPowerConsumptionCurve(const CurveQuadLinear& heatingPowerConsumptionCurve);
+      bool setHeatingPowerConsumptionCurve(const Curve& heatingPowerConsumptionCurve);
 
       //@}
       /** @name Other */
diff --git a/src/sdd/MapHVAC.cpp b/src/sdd/MapHVAC.cpp
index 37c410a0c1d..2604701be6a 100644
--- a/src/sdd/MapHVAC.cpp
+++ b/src/sdd/MapHVAC.cpp
@@ -2220,14 +2220,16 @@ namespace sdd {
           coil.setRatedHeatingCoefficientofPerformance(1.0 / _htPumpEIR.get());
         }
 
-        model::CurveQuadLinear heatingCapacityCurve = coil.heatingCapacityCurve();
+        model::Curve _heatingCapacityCurve = coil.heatingCapacityCurve();
+        model::CurveQuadLinear heatingCapacityCurve = _heatingCapacityCurve.cast<model::CurveQuadLinear>();
         heatingCapacityCurve.setCoefficient1Constant(-1.361311959);
         heatingCapacityCurve.setCoefficient2w(-2.471798046);
         heatingCapacityCurve.setCoefficient3x(4.173164514);
         heatingCapacityCurve.setCoefficient4y(0.640757401);
         heatingCapacityCurve.setCoefficient5z(0.0);
 
-        model::CurveQuadLinear heatingPowerConsumptionCurve = coil.heatingPowerConsumptionCurve();
+        model::Curve _heatingPowerConsumptionCurve = coil.heatingPowerConsumptionCurve();
+        model::CurveQuadLinear heatingPowerConsumptionCurve = _heatingPowerConsumptionCurve.cast<model::CurveQuadLinear>();
         heatingPowerConsumptionCurve.setCoefficient1Constant(-2.176941116);
         heatingPowerConsumptionCurve.setCoefficient2w(0.832114286);
         heatingPowerConsumptionCurve.setCoefficient3x(1.570743399);
@@ -3022,14 +3024,16 @@ namespace sdd {
           coil.setRatedCoolingCoefficientofPerformance(1.0 / _dxEIR.get());
         }
 
-        model::CurveQuadLinear totalCoolingCapacityCurve = coil.totalCoolingCapacityCurve();
+        model::Curve _totalCoolingCapacityCurve = coil.totalCoolingCapacityCurve();
+        model::CurveQuadLinear totalCoolingCapacityCurve = _totalCoolingCapacityCurve.cast<model::CurveQuadLinear>();
         totalCoolingCapacityCurve.setCoefficient1Constant(-9.149069561);
         totalCoolingCapacityCurve.setCoefficient2w(10.87814026);
         totalCoolingCapacityCurve.setCoefficient3x(-1.718780157);
         totalCoolingCapacityCurve.setCoefficient4y(0.746414818);
         totalCoolingCapacityCurve.setCoefficient5z(0.0);
 
-        model::CurveQuintLinear sensibleCoolingCapacityCurve = coil.sensibleCoolingCapacityCurve();
+        model::Curve _sensibleCoolingCapacityCurve = coil.sensibleCoolingCapacityCurve();
+        model::CurveQuintLinear sensibleCoolingCapacityCurve = _sensibleCoolingCapacityCurve.cast<model::CurveQuintLinear>();
         sensibleCoolingCapacityCurve.setCoefficient1Constant(-5.462690012);
         sensibleCoolingCapacityCurve.setCoefficient2v(17.95968138);
         sensibleCoolingCapacityCurve.setCoefficient3w(-11.87818402);
@@ -3037,7 +3041,8 @@ namespace sdd {
         sensibleCoolingCapacityCurve.setCoefficient5y(0.767285761);
         sensibleCoolingCapacityCurve.setCoefficient6z(0.0);
 
-        model::CurveQuadLinear coolingPowerConsumptionCurve = coil.coolingPowerConsumptionCurve();
+        model::Curve _coolingPowerConsumptionCurve = coil.coolingPowerConsumptionCurve();
+        model::CurveQuadLinear coolingPowerConsumptionCurve = _coolingPowerConsumptionCurve.cast<model::CurveQuadLinear>();
         coolingPowerConsumptionCurve.setCoefficient1Constant(-3.20456384);
         coolingPowerConsumptionCurve.setCoefficient2w(-0.976409399);
         coolingPowerConsumptionCurve.setCoefficient3x(3.97892546);


Test patch:
diff --git a/src/model/test/TableLookup_GTest.cpp b/src/model/test/TableLookup_GTest.cpp
index 0711d2c9fbd..4156343639d 100644
--- a/src/model/test/TableLookup_GTest.cpp
+++ b/src/model/test/TableLookup_GTest.cpp
@@ -15,6 +15,14 @@
 #include "../ModelObjectList_Impl.hpp"
 #include "../BoilerHotWater.hpp"
 #include "../BoilerHotWater_Impl.hpp"
+#include "../CoilCoolingWaterToAirHeatPumpEquationFit.hpp"
+#include "../CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp"
+#include "../CoilHeatingWaterToAirHeatPumpEquationFit.hpp"
+#include "../CoilHeatingWaterToAirHeatPumpEquationFit_Impl.hpp"
+#include "../CurveQuadLinear.hpp"
+#include "../CurveQuadLinear_Impl.hpp"
+#include "../CurveQuintLinear.hpp"
+#include "../CurveQuintLinear_Impl.hpp"
 
 using namespace openstudio;
 using namespace openstudio::model;
@@ -263,3 +271,125 @@ TEST_F(ModelFixture, TableLookup_Remove) {
     EXPECT_EQ(independentVariable1, tableLookup2.independentVariables().front());
   }
 }
+
+TEST_F(ModelFixture, TableLookup_CoilWaterToAirHeatPumpEquationFit) {
+  // Test for #4946 - WaterToAirHeatPumpEquationFit curves do not support Table:Lookup
+
+  Model m;
+
+  // test ctor 1
+  {
+    // ctor maintains backward compatibility
+    CoilCoolingWaterToAirHeatPumpEquationFit cc(m);
+    ASSERT_TRUE(cc.totalCoolingCapacityCurve().optionalCast<CurveQuadLinear>());
+    ASSERT_TRUE(cc.sensibleCoolingCapacityCurve().optionalCast<CurveQuintLinear>());
+    ASSERT_TRUE(cc.coolingPowerConsumptionCurve().optionalCast<CurveQuadLinear>());
+
+    CoilHeatingWaterToAirHeatPumpEquationFit ch(m);
+    ASSERT_TRUE(ch.heatingCapacityCurve().optionalCast<CurveQuadLinear>());
+    ASSERT_TRUE(ch.heatingPowerConsumptionCurve().optionalCast<CurveQuadLinear>());
+  }
+
+  // test ctor 2
+  {
+    // ctor maintains backward compatibility
+    CurveQuadLinear tccc(m);
+    CurveQuintLinear sccc(m);
+    CurveQuadLinear cpcc(m);
+    CoilCoolingWaterToAirHeatPumpEquationFit cc(m, tccc, sccc, cpcc);
+    ASSERT_TRUE(cc.totalCoolingCapacityCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(tccc, cc.totalCoolingCapacityCurve());
+    ASSERT_TRUE(cc.sensibleCoolingCapacityCurve().optionalCast<CurveQuintLinear>());
+    EXPECT_EQ(sccc, cc.sensibleCoolingCapacityCurve());
+    ASSERT_TRUE(cc.coolingPowerConsumptionCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(cpcc, cc.coolingPowerConsumptionCurve());
+
+    CurveQuadLinear hcc(m);
+    CurveQuadLinear hpcc(m);
+    CoilHeatingWaterToAirHeatPumpEquationFit ch(m, hcc, hpcc);
+    ASSERT_TRUE(ch.heatingCapacityCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(hcc, ch.heatingCapacityCurve());
+    ASSERT_TRUE(ch.heatingPowerConsumptionCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(hpcc, ch.heatingPowerConsumptionCurve());
+  }
+
+  {
+    // ctor can now handle table lookup curves
+    TableLookup tl1(m);
+    TableLookup tl2(m);
+    TableLookup tl3(m);
+    CoilCoolingWaterToAirHeatPumpEquationFit cc(m, tl1, tl2, tl3);
+    ASSERT_TRUE(cc.totalCoolingCapacityCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tl1, cc.totalCoolingCapacityCurve());
+    ASSERT_TRUE(cc.sensibleCoolingCapacityCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tl2, cc.sensibleCoolingCapacityCurve());
+    ASSERT_TRUE(cc.coolingPowerConsumptionCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tl3, cc.coolingPowerConsumptionCurve());
+
+    TableLookup tl4(m);
+    TableLookup tl5(m);
+    CoilHeatingWaterToAirHeatPumpEquationFit ch(m, tl4, tl5);
+    ASSERT_TRUE(ch.heatingCapacityCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tl4, ch.heatingCapacityCurve());
+    ASSERT_TRUE(ch.heatingPowerConsumptionCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tl5, ch.heatingPowerConsumptionCurve());
+  }
+
+  // test new setter/getter
+  {
+    CoilCoolingWaterToAirHeatPumpEquationFit cc(m);
+    CoilHeatingWaterToAirHeatPumpEquationFit ch(m);
+
+    // setter maintains backward compatibility
+    CurveQuadLinear cql1(m);
+    EXPECT_TRUE(cc.setTotalCoolingCapacityCurve(cql1));
+    ASSERT_TRUE(cc.totalCoolingCapacityCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(cql1, cc.totalCoolingCapacityCurve());
+
+    CurveQuintLinear cql2(m);
+    EXPECT_TRUE(cc.setSensibleCoolingCapacityCurve(cql2));
+    ASSERT_TRUE(cc.sensibleCoolingCapacityCurve().optionalCast<CurveQuintLinear>());
+    EXPECT_EQ(cql2, cc.sensibleCoolingCapacityCurve());
+
+    CurveQuadLinear cql3(m);
+    EXPECT_TRUE(cc.setCoolingPowerConsumptionCurve(cql3));
+    ASSERT_TRUE(cc.coolingPowerConsumptionCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(cql3, cc.coolingPowerConsumptionCurve());
+
+    CurveQuadLinear cql4(m);
+    EXPECT_TRUE(ch.setHeatingCapacityCurve(cql4));
+    ASSERT_TRUE(ch.heatingCapacityCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(cql4, ch.heatingCapacityCurve());
+
+    CurveQuadLinear cql5(m);
+    EXPECT_TRUE(ch.setHeatingPowerConsumptionCurve(cql5));
+    ASSERT_TRUE(ch.heatingPowerConsumptionCurve().optionalCast<CurveQuadLinear>());
+    EXPECT_EQ(cql5, ch.heatingPowerConsumptionCurve());
+
+    // setter can now handle table lookup curves
+    TableLookup tbl1(m);
+    EXPECT_TRUE(cc.setTotalCoolingCapacityCurve(tbl1));
+    ASSERT_TRUE(cc.totalCoolingCapacityCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tbl1, cc.totalCoolingCapacityCurve());
+
+    TableLookup tbl2(m);
+    EXPECT_TRUE(cc.setSensibleCoolingCapacityCurve(tbl2));
+    ASSERT_TRUE(cc.sensibleCoolingCapacityCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tbl2, cc.sensibleCoolingCapacityCurve());
+
+    TableLookup tbl3(m);
+    EXPECT_TRUE(cc.setCoolingPowerConsumptionCurve(tbl3));
+    ASSERT_TRUE(cc.coolingPowerConsumptionCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tbl3, cc.coolingPowerConsumptionCurve());
+
+    TableLookup tbl4(m);
+    EXPECT_TRUE(ch.setHeatingCapacityCurve(tbl4));
+    ASSERT_TRUE(ch.heatingCapacityCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tbl4, ch.heatingCapacityCurve());
+
+    TableLookup tbl5(m);
+    EXPECT_TRUE(ch.setHeatingPowerConsumptionCurve(tbl5));
+    ASSERT_TRUE(ch.heatingPowerConsumptionCurve().optionalCast<TableLookup>());
+    EXPECT_EQ(tbl5, ch.heatingPowerConsumptionCurve());
+  }
+}