-
Notifications
You must be signed in to change notification settings - Fork 392
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
CondFD Surface Heat Source Actuators #9151
Conversation
|
||
## Testing | ||
|
||
The "PythonPlugin1ZoneUncontrolledCondFD" test files will be modified to include usage of the new actuator. This file will be used to validate the model to ensure that energy is conserved and that the actuators are working as expected. |
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 all seems reasonable. Adding an actuator for adding heat gain to a layer should be fine as long as the energy is tracked in the right meters. My only caution would be to keep the code changes as minimal as possible to avoid interfering with other changes in the cond-fd module.
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.
The basic functionality for this work is in place. I can still add some unit testing, but it would be good to get some reviewer eyes on this whenever possible.
SurfaceFD(Surf).condMaterialActuators.allocate(state.dataConstruction->Construct(ConstrNum).TotLayers); | ||
SurfaceFD(Surf).specHeatMaterialActuators.allocate(state.dataConstruction->Construct(ConstrNum).TotLayers); | ||
SurfaceFD(Surf).condMaterialActuators.allocate(TotLayers); | ||
SurfaceFD(Surf).specHeatMaterialActuators.allocate(TotLayers); | ||
SurfaceFD(Surf).condNodeReport.allocate(TotNodes + 1); | ||
SurfaceFD(Surf).specHeatNodeReport.allocate(TotNodes + 1); | ||
SurfaceFD(Surf).heatSourceFluxMaterialActuators.allocate(TotLayers - 1); | ||
SurfaceFD(Surf).heatSourceFluxLayerReport.allocate(TotLayers - 1); | ||
SurfaceFD(Surf).heatSourceFluxEnergyLayerReport.allocate(TotLayers - 1); |
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.
Adding the new actuator, along with minor shuffling/refactoring.
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 has nothing to do with this PR, but (to me) the only acceptable use of auto
is right here.
auto & surfFD(SurfaceFD(Surf));
surf.condMaterialActuators.allocate(TotLayers);
surf.condMaterialActuators.allocate(TotLayers);
...
This is probably the number one thing we can do for line-shortening and code readability in EnergyPlus. This is not a great example of that, but just imagine if SurfaceFD(Surf) were actually state.dataCondFD->SurfaceFD(Surf)
.
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 started making another pass back through with this in mind after The Great State Refactor of 2020, but then pplz got grumpy. Maybe we can do some targeted application for the worst offenders.
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.
Really? I would have thought people would have gotten grumpy because of the #GreatStateRefactor2020 #MakeEnergyPlusStateAgain and that would be a way to ungrumpify them!
// only setup for heat source actuator for layers 1 to N-1 | ||
if (lay != TotLayers) { | ||
SurfaceFD(Surf).heatSourceFluxMaterialActuators(lay).actuatorName = actName; | ||
} |
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.
Setup new actuator for layer 1 to N-1.
// Setup EMS Actuator and Output Variables for Heat Flux | ||
// Only setup for layers 1 to N-1 | ||
for (int lay = 1; lay < state.dataConstruction->Construct(ConstrNum).TotLayers; ++lay) { | ||
EnergyPlus::SetupEMSActuator(state, | ||
"CondFD Surface Material Layer", | ||
SurfaceFD(SurfNum).heatSourceFluxMaterialActuators(lay).actuatorName, | ||
"Heat Flux", | ||
"[W/m2]", | ||
SurfaceFD(SurfNum).heatSourceFluxMaterialActuators(lay).isActuated, | ||
SurfaceFD(SurfNum).heatSourceFluxMaterialActuators(lay).actuatedValue); | ||
SetupOutputVariable(state, | ||
format("CondFD Heat Source Power After Layer {}", lay), | ||
OutputProcessor::Unit::W, | ||
SurfaceFD(SurfNum).heatSourceFluxLayerReport(lay), | ||
OutputProcessor::SOVTimeStepType::Zone, | ||
OutputProcessor::SOVStoreType::State, | ||
state.dataSurface->Surface(SurfNum).Name); | ||
SetupOutputVariable(state, | ||
format("CondFD Heat Source Energy After Layer {}", lay), | ||
OutputProcessor::Unit::J, | ||
SurfaceFD(SurfNum).heatSourceFluxEnergyLayerReport(lay), | ||
OutputProcessor::SOVTimeStepType::Zone, | ||
OutputProcessor::SOVStoreType::Summed, | ||
state.dataSurface->Surface(SurfNum).Name, | ||
_, | ||
"Electricity", | ||
"Heating", | ||
_, | ||
"Building"); |
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 EMS actuator and output variables.
for (Lay = 1; Lay <= TotNodes + 1; ++Lay) { // include inside face node | ||
for (int node = 1; node <= TotNodes + 1; ++node) { // include inside face node |
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.
Minor refactoring. These outputs are at the node level, not the "layer" level. Just changing the indexer here to reflect that.
Real64 const QSSFlux((surface.Area > 0.0) && (construct.SourceSinkPresent && Lay == construct.SourceAfterLayer) | ||
? (state.dataHeatBalFanSys->QRadSysSource(Surf) + state.dataHeatBalFanSys->QPVSysSource(Surf)) / surface.Area | ||
: 0.0); // Source/Sink flux value at a layer interface // Includes QPV Source | ||
Real64 QSSFlux = 0.0; | ||
if ((surface.Area > 0.0) && (construct.SourceSinkPresent && Lay == construct.SourceAfterLayer)) { | ||
// Source/Sink flux value at a layer interface // Includes QPV Source | ||
QSSFlux = (state.dataHeatBalFanSys->QRadSysSource(Surf) + state.dataHeatBalFanSys->QPVSysSource(Surf)) / surface.Area; | ||
} | ||
|
||
// Add EMS actuated value | ||
if (heatFluxActuator.isActuated) { | ||
Real64 actuatedVal = heatFluxActuator.actuatedValue; | ||
if (actuatedVal >= 0) { | ||
QSSFlux += heatFluxActuator.actuatedValue; | ||
} else { | ||
ShowSevereError(state, fmt::format("Surface: {}, Material: {}", surface.Name, mat.Name)); | ||
ShowContinueError(state, "EMS Actuator does not support negative values"); | ||
ShowFatalError(state, "Program terminates due to preceding conditions."); | ||
} | ||
|
||
// Update report variables | ||
auto &surfFD = state.dataHeatBalFiniteDiffMgr->SurfaceFD(Surf); | ||
surfFD.heatSourceFluxLayerReport(Lay) = QSSFlux * surface.Area; | ||
surfFD.heatSourceFluxEnergyLayerReport(Lay) = QSSFlux * surface.Area * state.dataGlobal->TimeStepZoneSec; | ||
} |
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.
Acuating here, which is an addition to whatever is also occurring due to the InternalHeatSource
object.
Output:Variable,*,CondFD Heat Source Power After Layer 1,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Power After Layer 2,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Power After Layer 3,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Power After Layer 4,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Power After Layer 5,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Power After Layer 6,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Energy After Layer 1,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Energy After Layer 2,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Energy After Layer 3,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Energy After Layer 4,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Energy After Layer 5,hourly; | ||
|
||
Output:Variable,*,CondFD Heat Source Energy After Layer 6,hourly; |
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 output variables.
12, !- End Month | ||
1, !- End Month |
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.
No need to run this file for a full year.
for surface_name in surfaces_names: | ||
constr = Construction(surface_name) | ||
constr.set_material_layers(wall_materials) | ||
self.surfaces.append(constr) | ||
|
||
# test surface for heat flux actuators | ||
wall_materials = ["Drywall 0.25 in. lay-1"] | ||
surfaces_names = ["Zn001:Wall004"] | ||
|
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.
Updating this file to actuate the heat source for one surface.
@mitchute @Myoldmopar it has been 28 days since this pull request was last updated. |
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.
A few initial comments.
// Actuator name format: "{SurfName}:{MaterialLayerName}" | ||
std::string actName = fmt::format("{}:{}", state.dataSurface->Surface(Surf).Name, state.dataMaterial->Material(matLay).Name); |
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.
All of this EMS setup here and below should be inside an if (state.dataGlobal->AnyEnergyManagementSystemInModel)
(well, as much of it as possible).
SetupOutputVariable(state, | ||
format("CondFD Heat Source Energy After Layer {}", lay), | ||
OutputProcessor::Unit::J, | ||
SurfaceFD(SurfNum).heatSourceFluxEnergyLayerReport(lay), |
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 like this is the total QSSFlux
which may include energy from Construction:InternalSource along with the actuator energy. This is fine as an output variable, but shouldn't be on the electric meter. You'll need a separate output variable for the meter, like "CondFD EMS Actuator Heat Source Energy After Layer {}"?
"[J/kg-C]", | ||
SurfaceFD(SurfNum).specHeatMaterialActuators(mat).isActuated, | ||
SurfaceFD(SurfNum).specHeatMaterialActuators(mat).actuatedValue); | ||
|
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.
@mjwitte I rearranged this to break out the internal source and EMS source values on separate output variables. The EMS value is now the only one on the meter.
I'm also only protecting the setup of the actuators and output variables here with AnyEnergyManagementSystemInModel
- it would be too big of a refactor to protect the rest of it with that flag.
@@ -107,4 +107,35 @@ \subsection{Surface Boundary Conditions}\label{surface-boundary-conditions} | |||
|
|||
\subsection{Conduction Finite Difference}\label{conduction-finite-difference} | |||
|
|||
Two actuators, called ``CondFD Surface Material Layer,'' are available with actuated component control types called ``Thermal Conductivity'' in [W/m-K] and ``Specific Heat'' in [J/kg-C]. These actuators are available in models that use the Conduction Finite Difference solution for conduction through surfaces. | |||
Several actuators, called ``CondFD Surface Material Layer,'' are available with actuated component control types for models that use the Conduction Finite Difference solution for conduction through surfaces. These are described below. |
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.
Updated EMS docs.
\paragraph{CondFD Internal Heat Source Power After Layer} | ||
|
||
This output is the heat power added after material layer N from the \hyperref[constructioninternalsource]{ConstructionProperty:InternalHeatSource} object. Only valid for the CondFD solution algorithm. | ||
|
||
\paragraph{CondFD Internal Heat Source Energy After Layer} | ||
|
||
This output is the heat energy added after material layer N from the \hyperref[constructioninternalsource]{ConstructionProperty:InternalHeatSource} object. Only valid for the CondFD solution algorithm. | ||
|
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.
Doc updates in the InternalSource object reflecting the new, conditionally-available output variables.
Diffs look reasonable here given the changes, and the clang-format error looks like a GHA error. @Myoldmopar do you need me to take a look at that?
Feel free to let me know if you see anything else here. |
That was really confusing. It's because the Clang-Format Github Action that we used was based specifically on Ubuntu Groovy, which is now out of support. We need to update to a newer version of that action. It looks like if we use 3.5.2 it will use Ubuntu Focal. (https://github.com/jidicula/clang-format-action/blob/v3.5.2/Dockerfile). We just need to change this line to use 3.5.2 and try it out. |
@Myoldmopar 3.5.2 works here. |
There's a branch with a bug fix (which will cause diffs) over here: https://github.com/NREL/EnergyPlus/tree/condfd-actuator-bug. That branch is downstream of this one, so once we merge this I'll file a new issue and PR for that one so the diffs and changes can be reviewed separately. |
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.
Unit tests run serially, modified idf/py runs to completion with a psych warning (didn't really check to see if the actuator actually actuates anything, but I'll assume it does).
So this is good to go. Merging.
Several actuators, called ``CondFD Surface Material Layer,'' are available with actuated component control types for models that use the Conduction Finite Difference solution for conduction through surfaces. These are described below. | ||
|
||
\begin{itemize} | ||
\item ``Thermal Conductivity''. Has units of [W/m-K]. Controls the thermal conductivity of the specified material layer within a given surface. Actuator is named from the surface name and material layer name combined with a colon ":". E.g. "SURFNAME:MATERIALLAYERNAME" |
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 line has some incorrect quotation marks, but that can be fixed in the next CondFD PR.
|
||
This output is the heat power added after material layer N from the \hyperref[constructioninternalsource]{ConstructionProperty:InternalHeatSource} object. Only valid for the CondFD solution algorithm. | ||
|
||
\paragraph{CondFD Internal Heat Source Energy After Layer} |
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.
The two new "CondFD EMS Heat Source ..." outputs should be here also. Again, in the next PR.
CondFD Surface Heat Source Actuators
Pull request overview