Skip to content

Commit

Permalink
Global EcoRoofMgr
Browse files Browse the repository at this point in the history
  • Loading branch information
dareumnam committed Mar 2, 2021
1 parent a12bdf0 commit efffc9b
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 78 deletions.
159 changes: 95 additions & 64 deletions src/EnergyPlus/EcoRoofManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,9 @@ namespace EcoRoofManager {
using namespace DataSurfaces;
using namespace DataHeatBalance;

Real64 CumRunoff(0.0); // Cumulative runoff, updated each time step (m) mult by roof area to get volume
Real64 CumET(0.0); // Cumulative evapotranspiration from soil and plants (m)
Real64 CumPrecip(0.0);
Real64 CumIrrigation(0.0); // Cumulative irrigation, updated each time step (m) mult by roof area to get volume
Real64 CurrentRunoff;
Real64 CurrentET;
Real64 CurrentPrecipitation; // units of (m) per timestep
Real64 CurrentIrrigation; // units of (m) per timestep

Real64 Tfold; // leaf temperature from the previous time step
Real64 Tgold; // ground temperature from the previous time step // TODO: These probably need to be re-initialized
bool EcoRoofbeginFlag(true);
bool CalcEcoRoofMyEnvrnFlag(true);

void clear_state() {
EcoRoofbeginFlag = true;
CalcEcoRoofMyEnvrnFlag = true;
}

Expand Down Expand Up @@ -320,8 +307,8 @@ namespace EcoRoofManager {
Latm = 1.0 * Sigma * 1.0 * Surface(SurfNum).ViewFactorGround * pow_4(state.dataEnvrn->GroundTempKelvin) +
1.0 * Sigma * 1.0 * Surface(SurfNum).ViewFactorSky * pow_4(state.dataEnvrn->SkyTempKelvin);

if (EcoRoofbeginFlag) {
EcoRoofbeginFlag = false;
if (state.dataEcoRoofMgr->EcoRoofbeginFlag) {
state.dataEcoRoofMgr->EcoRoofbeginFlag = false;
if (Surface(SurfNum).HeatTransferAlgorithm != HeatTransferModel_CTF)
ShowSevereError(state,
"CalcEcoRoof: EcoRoof simulation but HeatBalanceAlgorithm is not ConductionTransferFunction(CTF). EcoRoof model "
Expand Down Expand Up @@ -371,15 +358,57 @@ namespace EcoRoofManager {
SetupOutputVariable(state,
"Green Roof Soil Latent Heat Transfer Rate per Area", OutputProcessor::Unit::W_m2, Lg, "Zone", "State", "Environment");

SetupOutputVariable(state, "Green Roof Cumulative Precipitation Depth", OutputProcessor::Unit::m, CumPrecip, "Zone", "Sum", "Environment");
SetupOutputVariable(state, "Green Roof Cumulative Irrigation Depth", OutputProcessor::Unit::m, CumIrrigation, "Zone", "Sum", "Environment");
SetupOutputVariable(state, "Green Roof Cumulative Runoff Depth", OutputProcessor::Unit::m, CumRunoff, "Zone", "Sum", "Environment");
SetupOutputVariable(state, "Green Roof Cumulative Evapotranspiration Depth", OutputProcessor::Unit::m, CumET, "Zone", "Sum", "Environment");
SetupOutputVariable(state,
"Green Roof Current Precipitation Depth", OutputProcessor::Unit::m, CurrentPrecipitation, "Zone", "Sum", "Environment");
SetupOutputVariable(state, "Green Roof Current Irrigation Depth", OutputProcessor::Unit::m, CurrentIrrigation, "Zone", "Sum", "Environment");
SetupOutputVariable(state, "Green Roof Current Runoff Depth", OutputProcessor::Unit::m, CurrentRunoff, "Zone", "Sum", "Environment");
SetupOutputVariable(state, "Green Roof Current Evapotranspiration Depth", OutputProcessor::Unit::m, CurrentET, "Zone", "Sum", "Environment");
"Green Roof Cumulative Precipitation Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CumPrecip,
"Zone",
"Sum",
"Environment");
SetupOutputVariable(state,
"Green Roof Cumulative Irrigation Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CumIrrigation,
"Zone",
"Sum",
"Environment");
SetupOutputVariable(
state, "Green Roof Cumulative Runoff Depth", OutputProcessor::Unit::m, state.dataEcoRoofMgr->CumRunoff, "Zone", "Sum", "Environment");
SetupOutputVariable(state,
"Green Roof Cumulative Evapotranspiration Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CumET,
"Zone",
"Sum",
"Environment");
SetupOutputVariable(state,
"Green Roof Current Precipitation Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CurrentPrecipitation,
"Zone",
"Sum",
"Environment");
SetupOutputVariable(state,
"Green Roof Current Irrigation Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CurrentIrrigation,
"Zone",
"Sum",
"Environment");
SetupOutputVariable(state,
"Green Roof Current Runoff Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CurrentRunoff,
"Zone",
"Sum",
"Environment");
SetupOutputVariable(state,
"Green Roof Current Evapotranspiration Depth",
OutputProcessor::Unit::m,
state.dataEcoRoofMgr->CurrentET,
"Zone",
"Sum",
"Environment");

// DJS NOVEMBER 2010 - end of calls to setup output of ecoroof variables

Expand All @@ -397,20 +426,20 @@ namespace EcoRoofManager {
// DJS July 2007

if (state.dataGlobal->BeginEnvrnFlag && CalcEcoRoofMyEnvrnFlag) {
Tgold = OutDryBulbTempAt(state, Surface(SurfNum).Centroid.z); // OutDryBulbTemp ! initial guess
Tfold = OutDryBulbTempAt(state, Surface(SurfNum).Centroid.z); // OutDryBulbTemp ! initial guess
state.dataEcoRoofMgr->Tgold = OutDryBulbTempAt(state, Surface(SurfNum).Centroid.z); // OutDryBulbTemp ! initial guess
state.dataEcoRoofMgr->Tfold = OutDryBulbTempAt(state, Surface(SurfNum).Centroid.z); // OutDryBulbTemp ! initial guess
Tg = 10.0;
Tf = 10.0;
Vfluxf = 0.0;
Vfluxg = 0.0;
CumRunoff = 0.0;
CumET = 0.0;
CumPrecip = 0.0;
CumIrrigation = 0.0;
CurrentRunoff = 0.0;
CurrentET = 0.0;
CurrentPrecipitation = 0.0;
CurrentIrrigation = 0.0;
state.dataEcoRoofMgr->CumRunoff = 0.0;
state.dataEcoRoofMgr->CumET = 0.0;
state.dataEcoRoofMgr->CumPrecip = 0.0;
state.dataEcoRoofMgr->CumIrrigation = 0.0;
state.dataEcoRoofMgr->CurrentRunoff = 0.0;
state.dataEcoRoofMgr->CurrentET = 0.0;
state.dataEcoRoofMgr->CurrentPrecipitation = 0.0;
state.dataEcoRoofMgr->CurrentIrrigation = 0.0;
CalcEcoRoofMyEnvrnFlag = false;
}

Expand All @@ -424,8 +453,8 @@ namespace EcoRoofManager {
state, Moisture, MeanRootMoisture, MoistureMax, MoistureResidual, SoilThickness, Vfluxf, Vfluxg, ConstrNum, Alphag, unit, Tg, Tf, Qsoil);

Ta = OutDryBulbTempAt(state, Surface(SurfNum).Centroid.z); // temperature outdoor - Surface is dry, use normal correlation
Tg = Tgold;
Tf = Tfold;
Tg = state.dataEcoRoofMgr->Tgold;
Tf = state.dataEcoRoofMgr->Tfold;

if (state.dataConstruction->Construct(ConstrNum).CTFCross(0) > 0.01) {
QuickConductionSurf = true;
Expand Down Expand Up @@ -516,7 +545,7 @@ namespace EcoRoofManager {
// equation is Henderson-Sellers (1984)
Lef = 1.91846e6 * pow_2((Tif + DataGlobalConstants::KelvinConv) / (Tif + DataGlobalConstants::KelvinConv - 33.91));
// Check to see if ice is sublimating or frost is forming.
if (Tfold < 0.0) Lef = 2.838e6; // per FASST documentation p.15 after eqn. 37.
if (state.dataEcoRoofMgr->Tfold < 0.0) Lef = 2.838e6; // per FASST documentation p.15 after eqn. 37.

// Derivative of Saturation vapor pressure, which is used in the calculation of
// derivative of saturation specific humidity.
Expand All @@ -532,7 +561,7 @@ namespace EcoRoofManager {
// Latent heat vaporization at the ground temperature
Leg = 1.91846e6 * pow_2(Tgk / (Tgk - 33.91));
// Check to see if ice is sublimating or frost is forming.
if (Tgold < 0.0) Leg = 2.838e6; // per FASST documentation p.15 after eqn. 37.
if (state.dataEcoRoofMgr->Tgold < 0.0) Leg = 2.838e6; // per FASST documentation p.15 after eqn. 37.

Desg = 611.2 * std::exp(17.67 * (Tg / (Tg + DataGlobalConstants::KelvinConv - 29.65))) *
(17.67 * Tg * (-1.0) * std::pow(Tg + DataGlobalConstants::KelvinConv - 29.65, -2) + 17.67 / (DataGlobalConstants::KelvinConv - 29.65 + Tg));
Expand Down Expand Up @@ -650,14 +679,14 @@ namespace EcoRoofManager {

} // This loop does an iterative solution of the simultaneous equations
Qsoil = -1.0 * (Qsoilpart1 - Qsoilpart2 * (SoilTK - DataGlobalConstants::KelvinConv)); // This is heat flux INTO top of the soil
Tfold = LeafTK - DataGlobalConstants::KelvinConv;
Tgold = SoilTK - DataGlobalConstants::KelvinConv;
state.dataEcoRoofMgr->Tfold = LeafTK - DataGlobalConstants::KelvinConv;
state.dataEcoRoofMgr->Tgold = SoilTK - DataGlobalConstants::KelvinConv;

} // if firstecosurface (if not we do NOT need to recalculate ecoroof energybalance as all ecoroof surfaces MUST be the same
// this endif was moved here from the if statement regarding whether we are looking at the first ecoroof surface or not.

TH(1, 1, SurfNum) = Tgold; // SoilTemperature
TempExt = Tgold;
TH(1, 1, SurfNum) = state.dataEcoRoofMgr->Tgold; // SoilTemperature
TempExt = state.dataEcoRoofMgr->Tgold;
}

void UpdateSoilProps(EnergyPlusData &state,
Expand Down Expand Up @@ -825,47 +854,47 @@ namespace EcoRoofManager {
UpdatebeginFlag = false;
}

CurrentRunoff = 0.0; // Initialize current time step runoff as it is used in several spots below...
state.dataEcoRoofMgr->CurrentRunoff = 0.0; // Initialize current time step runoff as it is used in several spots below...

// FIRST Subtract water evaporated by plants and at soil surface
Moisture -= (Vfluxg)*state.dataGlobal->MinutesPerTimeStep * 60.0 / TopDepth; // soil surface evaporation
MeanRootMoisture -= (Vfluxf)*state.dataGlobal->MinutesPerTimeStep * 60.0 / RootDepth; // plant extraction from root zone

// NEXT Update evapotranspiration summary variable for print out
CurrentET = (Vfluxg + Vfluxf) * state.dataGlobal->MinutesPerTimeStep * 60.0; // units are meters
state.dataEcoRoofMgr->CurrentET = (Vfluxg + Vfluxf) * state.dataGlobal->MinutesPerTimeStep * 60.0; // units are meters
if (!state.dataGlobal->WarmupFlag) {
CumET += CurrentET;
state.dataEcoRoofMgr->CumET += state.dataEcoRoofMgr->CurrentET;
}

// NEXT Add Precipitation to surface soil moisture variable (if a schedule exists)
if (!state.dataGlobal->WarmupFlag) {
CurrentPrecipitation = 0.0; // first initialize to zero
state.dataEcoRoofMgr->CurrentPrecipitation = 0.0; // first initialize to zero
}
CurrentPrecipitation = 0.0; // first initialize to zero
state.dataEcoRoofMgr->CurrentPrecipitation = 0.0; // first initialize to zero
if (state.dataWaterData->RainFall.ModeID == DataWater::RainfallMode::RainSchedDesign) {
CurrentPrecipitation = state.dataWaterData->RainFall.CurrentAmount; // units of m
Moisture += CurrentPrecipitation / TopDepth; // x (m) evenly put into top layer
state.dataEcoRoofMgr->CurrentPrecipitation = state.dataWaterData->RainFall.CurrentAmount; // units of m
Moisture += state.dataEcoRoofMgr->CurrentPrecipitation / TopDepth; // x (m) evenly put into top layer
if (!state.dataGlobal->WarmupFlag) {
CumPrecip += CurrentPrecipitation;
state.dataEcoRoofMgr->CumPrecip += state.dataEcoRoofMgr->CurrentPrecipitation;
}
}

// NEXT Add Irrigation to surface soil moisture variable (if a schedule exists)
CurrentIrrigation = 0.0; // first initialize to zero
state.dataEcoRoofMgr->CurrentIrrigation = 0.0; // first initialize to zero
state.dataWaterData->Irrigation.ActualAmount = 0.0;
if (state.dataWaterData->Irrigation.ModeID == DataWater::RainfallMode::IrrSchedDesign) {
CurrentIrrigation = state.dataWaterData->Irrigation.ScheduledAmount; // units of m
state.dataWaterData->Irrigation.ActualAmount = CurrentIrrigation;
state.dataEcoRoofMgr->CurrentIrrigation = state.dataWaterData->Irrigation.ScheduledAmount; // units of m
state.dataWaterData->Irrigation.ActualAmount = state.dataEcoRoofMgr->CurrentIrrigation;
// elseif (Irrigation%ModeID ==IrrSmartSched .and. moisture .lt. 0.4d0*MoistureMax) then
} else if (state.dataWaterData->Irrigation.ModeID == DataWater::RainfallMode::IrrSmartSched && Moisture < state.dataWaterData->Irrigation.IrrigationThreshold * MoistureMax) {
// Smart schedule only irrigates when scheduled AND the soil is less than 40% saturated
CurrentIrrigation = state.dataWaterData->Irrigation.ScheduledAmount; // units of m
state.dataWaterData->Irrigation.ActualAmount = CurrentIrrigation;
state.dataEcoRoofMgr->CurrentIrrigation = state.dataWaterData->Irrigation.ScheduledAmount; // units of m
state.dataWaterData->Irrigation.ActualAmount = state.dataEcoRoofMgr->CurrentIrrigation;
}

Moisture += CurrentIrrigation / TopDepth; // irrigation in (m)/timestep put into top layer
Moisture += state.dataEcoRoofMgr->CurrentIrrigation / TopDepth; // irrigation in (m)/timestep put into top layer
if (!state.dataGlobal->WarmupFlag) {
CumIrrigation += CurrentIrrigation;
state.dataEcoRoofMgr->CumIrrigation += state.dataEcoRoofMgr->CurrentIrrigation;
}

// Note: If soil top layer gets a massive influx of rain &/or irrigation some of
Expand All @@ -880,16 +909,18 @@ namespace EcoRoofManager {
// I suspect that 15 minute intervals may be needed. Another option is to have an internal moisture
// overflow bin that will hold extra moisture and then distribute it in subsequent hours. This way the
// soil still gets the same total moisture... it is just distributed over a longer period.
if (CurrentIrrigation + CurrentPrecipitation > 0.5 * 0.0254 * state.dataGlobal->MinutesPerTimeStep / 60.0) {
CurrentRunoff = CurrentIrrigation + CurrentPrecipitation - (0.5 * 0.0254 * state.dataGlobal->MinutesPerTimeStep / 60.0);
if (state.dataEcoRoofMgr->CurrentIrrigation + state.dataEcoRoofMgr->CurrentPrecipitation >
0.5 * 0.0254 * state.dataGlobal->MinutesPerTimeStep / 60.0) {
state.dataEcoRoofMgr->CurrentRunoff = state.dataEcoRoofMgr->CurrentIrrigation + state.dataEcoRoofMgr->CurrentPrecipitation -
(0.5 * 0.0254 * state.dataGlobal->MinutesPerTimeStep / 60.0);
// If we get here then TOO much moisture has already been added to soil (must now subtract excess)
Moisture -= CurrentRunoff / TopDepth; // currently any incident moisture in excess of 1/4 " per hour
Moisture -= state.dataEcoRoofMgr->CurrentRunoff / TopDepth; // currently any incident moisture in excess of 1/4 " per hour
// simply runs off the top of the soil.
}
// Now, if top layer is beyond saturation... the excess simply runs off without penetrating into the lower
// layers.
if (Moisture > MoistureMax) {
CurrentRunoff += (Moisture - MoistureMax) * TopDepth;
state.dataEcoRoofMgr->CurrentRunoff += (Moisture - MoistureMax) * TopDepth;
Moisture = MoistureMax;
}

Expand Down Expand Up @@ -978,7 +1009,7 @@ namespace EcoRoofManager {
// Now limit the soil from going over the moisture maximum and takes excess to create runoff
if (Moisture >= MoistureMax) { // This statement makes sure that the top layer is not over the moisture maximum for the soil.
Moisture = 0.9999 * MoistureMax; // then it takes any moisture over the maximum amount and makes it runoff
CurrentRunoff += (Moisture - MoistureMax * 0.9999) * TopDepth;
state.dataEcoRoofMgr->CurrentRunoff += (Moisture - MoistureMax * 0.9999) * TopDepth;
}

// Now make sure that the soil does not go below the moisture minimum
Expand All @@ -1003,7 +1034,7 @@ namespace EcoRoofManager {
// Limit the moisture from going over the saturation limit and create runoff:
if (MeanRootMoisture >= MoistureMax) {
MeanRootMoisture = 0.9999 * MoistureMax;
CurrentRunoff += (Moisture - MoistureMax * 0.9999) * RootDepth;
state.dataEcoRoofMgr->CurrentRunoff += (Moisture - MoistureMax * 0.9999) * RootDepth;
}

// Limit the soil from going below the soil saturation limit:
Expand All @@ -1012,15 +1043,15 @@ namespace EcoRoofManager {
}

// Next, track runoff from the bottom of the soil:
CurrentRunoff += SoilConductivityAveRoot * TimeStepZoneSec;
state.dataEcoRoofMgr->CurrentRunoff += SoilConductivityAveRoot * TimeStepZoneSec;

//~~~END SF EDITS
}

// NEXT Limit moisture values to saturation (create RUNOFF that we can track)
// CurrentRunoff is sum of "overwatering" in a timestep and excess moisture content
if (!state.dataGlobal->WarmupFlag) {
CumRunoff += CurrentRunoff;
state.dataEcoRoofMgr->CumRunoff += state.dataEcoRoofMgr->CurrentRunoff;
}

if (MeanRootMoisture <= MoistureResidual * 1.00001) {
Expand Down
Loading

5 comments on commit efffc9b

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

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

GlobalEcoRoof (dareumnam) - x86_64-MacOS-10.15-clang-11.0.0: OK (3056 of 3059 tests passed, 0 test warnings)

Messages:\n

  • 3 tests had: AUD diffs.
  • 3 tests had: EIO diffs.
  • 3 tests had: ERR diffs.
  • 3 tests had: MTR big diffs.
  • 3 tests had: RDD diffs.
  • 3 tests had: SSZ big diffs.
  • 3 tests had: ZSZ big diffs.
  • 3 tests had: Table big diffs.
  • 1 test had: ESO big diffs.
  • 1 test had: MTD diffs.

Failures:\n

regression Test Summary

  • Passed: 719
  • Failed: 3

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

GlobalEcoRoof (dareumnam) - x86_64-Linux-Ubuntu-18.04-gcc-7.5: OK (3096 of 3099 tests passed, 0 test warnings)

Messages:\n

  • 3 tests had: AUD diffs.
  • 3 tests had: EIO diffs.
  • 3 tests had: MTR big diffs.
  • 3 tests had: RDD diffs.
  • 3 tests had: SSZ big diffs.
  • 3 tests had: ZSZ big diffs.
  • 3 tests had: Table big diffs.
  • 1 test had: ERR diffs.
  • 1 test had: ESO big diffs.
  • 1 test had: MTD diffs.

Failures:\n

regression Test Summary

  • Passed: 739
  • Failed: 3

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

GlobalEcoRoof (dareumnam) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-UnitTestsCoverage-Debug: OK (1613 of 1613 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

GlobalEcoRoof (dareumnam) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-IntegrationCoverage-Debug: OK (726 of 727 tests passed, 0 test warnings)

Failures:\n

integration Test Summary

  • Passed: 726
  • Timeout: 1

Build Badge Test Badge Coverage Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

GlobalEcoRoof (dareumnam) - Win64-Windows-10-VisualStudio-16: OK (2308 of 2308 tests passed, 0 test warnings)

Build Badge Test Badge

Please sign in to comment.