-
Notifications
You must be signed in to change notification settings - Fork 195
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
Fix #4802 - E+ 23.1.0: Wrap SolarCollectorPerformance:PhotovoltaicThermal:BIPVT #4813
Conversation
…ing to be wrapped just yet)
…dio.idd Just adding the Handle
…oltaicThermal:BIPVT
``` $os_build_rel/Products/openstudio GenerateClass.rb -c "SolarCollectorPerformancePhotovoltaicThermalBIPVT" -b "ModelObject" -i "OS:SolarCollectorPerformance:PhotovoltaicThermal:BIPVT" -s model -o /Users/julien/Software/Others/OpenStudio/src/model/ -p -f -r ```
…solarCollectorPerformance: it now retuerns a ModelObject and not a SolarCollectorPerformancePhotovoltaicThermalSimple
@@ -5118,6 +5118,36 @@ MaterialProperty:VariableThermalConductivity, | |||
\note for Temperature-Thermal Conductivity function corresponding to temperature 1 | |||
\units W/m-K | |||
|
|||
MaterialProperty:VariableAbsorptance, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sneaking this in (unrelated to this PR), right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I realized between this PR and the ones you added so far, it was going to be the only missing one. See commit message of 90005f1
…atPlatePhotovoltaicThermal isn't RT'ed, neither is SurfacePropertyOtherSideConditionsModel)
…e RT for this + BIPVT
…, remove defaulted one)
…ertyOtherSideConditionsModel to avoid creating a default one
* [#4813](https://github.com/NREL/OpenStudio/pull/4813) - Wrap `SolarCollectorPerformance:PhotovoltaicThermal:BIPVT` | ||
* `SolarCollectorFlatPlatePhotovoltaicThermal` has API-breaking changes in the `solarCollectorPerformance` getter due to the addition of this new object: it used to return a `SolarCollectorPerformancePhotovoltaicThermalSimple` (the only performance object at the time), now it's a `ModelObject`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document API break in SolarCollectorFlatPlatePhotovoltaicThermal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
A3 , \field Control Signal | ||
\type choice | ||
\key SurfaceTemperature | ||
\key SurfaceReceivedSolarRadiation | ||
\key SpaceHeatingCoolingMode | ||
\key Scheduled | ||
\default SurfaceTemperature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MaterialProperty:VariableAbsorptance
: I removed the \required-field
in E+ idd since it already has a \default
@@ -70,7 +73,7 @@ namespace model { | |||
/** @name Getters */ | |||
//@{ | |||
|
|||
SolarCollectorPerformancePhotovoltaicThermalSimple solarCollectorPerformance() const; | |||
ModelObject solarCollectorPerformance() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API break in SolarCollectorFlatPlatePhotovoltaicThermal
. It is unavoidable, now that we have two potential Performance objects.
I am considering adding a base (shallow) class SolarCollectorPerformancePhotovoltaicThermal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
/// Deletes the current performance and clones the performance passed in | ||
bool setSolarCollectorPerformance(const SolarCollectorPerformancePhotovoltaicThermalBIPVT& performance); | ||
bool setSolarCollectorPerformance(const SolarCollectorPerformancePhotovoltaicThermalSimple& performance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like changing the parameter type to the overly generic "ModelObject" one here. It would work fine if you passed any ModelObject and just return false
but that's silent-ish. Whether constraining the Type would create a type error message with the prototype(s) accepted.
That is the reason I am considering a base class SolarCollectorPerformancePhotovoltaicThermal
here. But maybe it's too much complexity.
So so far I've used two specific overloads for the setter. The only annoyance is that you need to cast if you retrieve the performance from one object to set to another.
-pvt2.setPerformance(pvt.performance())
+pvt2.setperformance(pvt.performance().to_SolarCollectorPerformancePhotovoltaicThermalSimple)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems consistent with how we've been breaking API in the recent past...
@@ -195,7 +195,7 @@ namespace model { | |||
boost::optional<SurfacePropertyOtherSideCoefficients> surfacePropertyOtherSideCoefficients() const; | |||
|
|||
/** Sets the SurfacePropertyOtherSideCoefficients. */ | |||
bool setSurfacePropertyOtherSideCoefficients(SurfacePropertyOtherSideCoefficients& otherSideCoefficients); | |||
bool setSurfacePropertyOtherSideCoefficients(const SurfacePropertyOtherSideCoefficients& otherSideCoefficients); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't exactly related to this PR but I noticed the const-correctness issue while creating a GTest (It was forcing me to create a temporary before I could use these)
setSurfacePropertyOtherSideCoefficients / setSurfacePropertyOtherSideConditionsModel in both Surface and SubSurface need to have a const.
{ | ||
Model m; | ||
SolarCollectorFlatPlatePhotovoltaicThermal testObject(m); | ||
auto performance = testObject.solarCollectorPerformance(); | ||
EXPECT_TRUE(performance.optionalCast<SolarCollectorPerformancePhotovoltaicThermalSimple>()); | ||
} | ||
{ | ||
Model m; | ||
SolarCollectorPerformancePhotovoltaicThermalSimple performance(m); | ||
SolarCollectorFlatPlatePhotovoltaicThermal testObject(performance); | ||
EXPECT_TRUE(performance.optionalCast<SolarCollectorPerformancePhotovoltaicThermalSimple>()); | ||
EXPECT_EQ(testObject.solarCollectorPerformance(), performance); | ||
} | ||
{ | ||
Model m; | ||
SolarCollectorPerformancePhotovoltaicThermalBIPVT performance(m); | ||
SolarCollectorFlatPlatePhotovoltaicThermal testObject(performance); | ||
EXPECT_TRUE(performance.optionalCast<SolarCollectorPerformancePhotovoltaicThermalBIPVT>()); | ||
EXPECT_EQ(testObject.solarCollectorPerformance(), performance); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test the new explicit ctors for the Solar Collector PVT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
* that means correct node names in the ChillerElectricASHRAE205 but also | ||
* on the Branches | ||
*/ | ||
TEST_F(EnergyPlusFixture, ForwardTranslator_SolarCollectorPerformancePhotovoltaicThermalBIPVT) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Full FT test
|
||
namespace energyplus { | ||
|
||
boost::optional<ModelObject> ReverseTranslator::translateSurfacePropertyOtherSideConditionsModel(const WorkspaceObject& workspaceObject) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New RT for SurfacePropertyOtherSideConditionsModel, I needed this so the BIPVT one would not be too useless.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see.
// Boundary Conditions Model Name: Required Object | ||
if (boost::optional<WorkspaceObject> wo_ = | ||
workspaceObject.getTarget(SolarCollectorPerformance_PhotovoltaicThermal_BIPVTFields::BoundaryConditionsModelName)) { | ||
if (boost::optional<ModelObject> mo_ = translateAndMapWorkspaceObject(wo_.get())) { | ||
// TODO: check return types | ||
if (boost::optional<SurfacePropertyOtherSideConditionsModel> boundaryConditionsModel_ = | ||
mo_->optionalCast<SurfacePropertyOtherSideConditionsModel>()) { | ||
// The Ctor creates a BoundaryConditionsModel for us, so we can remove it now that we found the right one | ||
auto defaultOSCM = modelObject.boundaryConditionsModel(); | ||
modelObject.setBoundaryConditionsModel(boundaryConditionsModel_.get()); | ||
defaultOSCM.remove(); | ||
} else { | ||
LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Boundary Conditions Model Name'"); | ||
} | ||
} else { | ||
LOG(Error, "For " << workspaceObject.briefDescription() | ||
<< ", cannot reverse translate required object 'Boundary Conditions Model Name'. Using defaulted one."); | ||
} | ||
LOG(Warn, | ||
"For " << workspaceObject.briefDescription() << ", cannot find required object 'Boundary Conditions Model Name'. Using defaulted one."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BIPVT: just warn if the OSCM can't be found (and keep using the defaulted one).
case openstudio::IddObjectType::SolarCollectorPerformance_PhotovoltaicThermal_BIPVT: { | ||
modelObject = translateSolarCollectorPerformancePhotovoltaicThermalBIPVT(workspaceObject); | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm adding the RT for the future mostly, since the SolarCollectorPVT isn't RT'ed (since PlantLoop isn't).
But this can still be useful if you want to grab the Perf data from an IDF to assign to a model-time created SolarCollectorPVT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final walkthrough comments. This is ready for review. Not sure who wants to review: @joseph-robertson @tijcolem
} // namespace detail | ||
|
||
/** SolarCollectorPerformancePhotovoltaicThermalBIPVT is a ModelObject that wraps the OpenStudio IDD object 'OS:SolarCollectorPerformance:PhotovoltaicThermal:BIPVT'. */ | ||
class MODEL_API SolarCollectorPerformancePhotovoltaicThermalBIPVT : public ModelObject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I made this a ModelObject
because the SolarCollectorPerformancePhotovoltaicThermalSimple
already was. I kinda find it weird that these aren't ResourceObjects, and that the SolarCollectorPVT just clones whatever Perf object you pass, but that's the way it is, I didn't want to break API.
OpenStudio/src/model/SolarCollectorFlatPlatePhotovoltaicThermal.cpp
Lines 181 to 198 in 2c46784
bool SolarCollectorFlatPlatePhotovoltaicThermal_Impl::setSolarCollectorPerformance( | |
const SolarCollectorPerformancePhotovoltaicThermalSimple& performance) { | |
bool result(false); | |
SolarCollectorPerformancePhotovoltaicThermalSimple current = this->solarCollectorPerformance(); | |
if (current.handle() == performance.handle()) { | |
return true; // no-op | |
} | |
ModelObject clone = performance.clone(this->model()); | |
result = setSolarCollectorPerformanceNoClone(clone.cast<SolarCollectorPerformancePhotovoltaicThermalSimple>()); | |
if (result) { | |
current.remove(); | |
} else { | |
result = setSolarCollectorPerformanceNoClone(current); | |
OS_ASSERT(result); | |
return false; | |
} | |
return result; | |
} |
CI Results for 8361971:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Just a few clarifying questions.
* [#4813](https://github.com/NREL/OpenStudio/pull/4813) - Wrap `SolarCollectorPerformance:PhotovoltaicThermal:BIPVT` | ||
* `SolarCollectorFlatPlatePhotovoltaicThermal` has API-breaking changes in the `solarCollectorPerformance` getter due to the addition of this new object: it used to return a `SolarCollectorPerformancePhotovoltaicThermalSimple` (the only performance object at the time), now it's a `ModelObject`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
OS:SolarCollectorPerformance:PhotovoltaicThermal:BIPVT, | ||
\memo Thermal performance parameters for Building-Integrated Photovoltaic-Thermal (BIPVT) solar collector. | ||
\min-fields 17 | ||
A1, \field Handle | ||
\type handle | ||
\required-field | ||
A2 , \field Name | ||
\required-field | ||
\type alpha | ||
\reference FlatPlatePVTParameters | ||
A3, \field Boundary Conditions Model Name | ||
\required-field | ||
\type object-list | ||
\object-list OSCMNames | ||
\note Enter the name of a SurfaceProperty:OtherSideConditionsModel object | ||
A4 , \field Availability Schedule Name | ||
\note Availability schedule name for this collector. Schedule value > 0 means it is available. | ||
\note If this field is blank, the collector is always available. | ||
\type object-list | ||
\object-list ScheduleNames | ||
\required-field | ||
N1 , \field Effective Plenum Gap Thickness Behind PV Modules | ||
\required-field | ||
\type real | ||
\units m | ||
\minimum> 0.0 | ||
N2 , \field PV Cell Normal Transmittance-Absorptance Product | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N3 , \field Backing Material Normal Transmittance-Absorptance Product | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N4 , \field Cladding Normal Transmittance-Absorptance Product | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N5 , \field Fraction of Collector Gross Area Covered by PV Module | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N6 , \field Fraction of PV Cell Area to PV Module Area | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N7 , \field PV Module Top Thermal Resistance | ||
\type real | ||
\units m2-K/W | ||
\required-field | ||
\minimum> 0.0 | ||
N8 , \field PV Module Bottom Thermal Resistance | ||
\type real | ||
\units m2-K/W | ||
\required-field | ||
\minimum> 0.0 | ||
N9 ,\field PV Module Front Longwave Emissivity | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N10 ,\field PV Module Back Longwave Emissivity | ||
\type real | ||
\required-field | ||
\minimum> 0.0 | ||
\maximum< 1.00 | ||
N11 ,\field Glass Thickness | ||
\type real | ||
\required-field | ||
\units m | ||
\minimum> 0.0 | ||
\maximum< 0.01 | ||
N12 ,\field Glass Refraction Index | ||
\type real | ||
\required-field | ||
\minimum> 1.0 | ||
\maximum< 10.00 | ||
N13 ;\field Glass Extinction Coefficient | ||
\type real | ||
\required-field | ||
\units 1/m | ||
\minimum> 0.0 | ||
\maximum< 100.00 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -394,12 +395,12 @@ set(${target_name}_src | |||
ForwardTranslator/ForwardTranslateSurfacePropertyConvectionCoefficients.cpp | |||
ForwardTranslator/ForwardTranslateSurfacePropertyConvectionCoefficientsMultipleSurface.cpp | |||
ForwardTranslator/ForwardTranslateSurfacePropertyExposedFoundationPerimeter.cpp | |||
ForwardTranslator/ForwardTranslateSurfacePropertyGroundSurfaces.cpp | |||
ForwardTranslator/ForwardTranslateSurfacePropertyIncidentSolarMultiplier.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphabetizing.
ReverseTranslator/ReverseTranslateSurfacePropertyGroundSurfaces.cpp | ||
ReverseTranslator/ReverseTranslateSurfacePropertyIncidentSolarMultiplier.cpp | ||
ReverseTranslator/ReverseTranslateSurfacePropertyLocalEnvironment.cpp | ||
ReverseTranslator/ReverseTranslateSurfacePropertyOtherSideConditionsModel.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphabetizing, and new RT for existing object.
|
||
namespace energyplus { | ||
|
||
boost::optional<ModelObject> ReverseTranslator::translateSurfacePropertyOtherSideConditionsModel(const WorkspaceObject& workspaceObject) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see.
@@ -70,7 +73,7 @@ namespace model { | |||
/** @name Getters */ | |||
//@{ | |||
|
|||
SolarCollectorPerformancePhotovoltaicThermalSimple solarCollectorPerformance() const; | |||
ModelObject solarCollectorPerformance() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
/// Deletes the current performance and clones the performance passed in | ||
bool setSolarCollectorPerformance(const SolarCollectorPerformancePhotovoltaicThermalBIPVT& performance); | ||
bool setSolarCollectorPerformance(const SolarCollectorPerformancePhotovoltaicThermalSimple& performance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems consistent with how we've been breaking API in the recent past...
|
||
/// Deletes the current parameters and constructs a new default set of parameters | ||
/// Deletes the current performance and constructs a new default set of performance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I missed it, but where does it actually construct a new default set of performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it now.
{ | ||
Model m; | ||
SolarCollectorFlatPlatePhotovoltaicThermal testObject(m); | ||
auto performance = testObject.solarCollectorPerformance(); | ||
EXPECT_TRUE(performance.optionalCast<SolarCollectorPerformancePhotovoltaicThermalSimple>()); | ||
} | ||
{ | ||
Model m; | ||
SolarCollectorPerformancePhotovoltaicThermalSimple performance(m); | ||
SolarCollectorFlatPlatePhotovoltaicThermal testObject(performance); | ||
EXPECT_TRUE(performance.optionalCast<SolarCollectorPerformancePhotovoltaicThermalSimple>()); | ||
EXPECT_EQ(testObject.solarCollectorPerformance(), performance); | ||
} | ||
{ | ||
Model m; | ||
SolarCollectorPerformancePhotovoltaicThermalBIPVT performance(m); | ||
SolarCollectorFlatPlatePhotovoltaicThermal testObject(performance); | ||
EXPECT_TRUE(performance.optionalCast<SolarCollectorPerformancePhotovoltaicThermalBIPVT>()); | ||
EXPECT_EQ(testObject.solarCollectorPerformance(), performance); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
// Bad Value | ||
EXPECT_FALSE(solarCollectorPerformancePhotovoltaicThermalBIPVT.setGlassExtinctionCoefficient(-10.0)); | ||
EXPECT_EQ(94.444, solarCollectorPerformancePhotovoltaicThermalBIPVT.glassExtinctionCoefficient()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We check for clone, remove, etc. in parent Thermal test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
Pull request overview
Pull Request Author
src/model/test
)src/energyplus/Test
)src/osversion/VersionTranslator.cpp
)Labels:
IDDChange
APIChange
Pull Request - Ready for CI
so that CI builds your PRReview Checklist
This will not be exhaustively relevant to every PR.