Skip to content

Commit 9431a00

Browse files
authored
Merge pull request #108 from cse-sim/reportinfil
AFMETER fixes / documentation / test case
2 parents dc8f71c + 19b0ebf commit 9431a00

File tree

11 files changed

+1546
-1397
lines changed

11 files changed

+1546
-1397
lines changed

doc/src/cse-user-manual.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ sections:
4343
- [2, "records/glazetype.md"]
4444
- [2, "records/meter.md"]
4545
- [2, "records/dhwmeter.md"]
46+
- [2, "records/afmeter.md"]
4647
- [2, "records/zone.md"]
4748
- [2, "records/gain.md"]
4849
- [2, "records/surface.md"]

doc/src/records/afmeter.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# AFMETER
2+
3+
An AFMETER object is a user-defined "device" that records zone air flows as simulated by CSE. The user defines AFMETERs and assigns them to zones (see ZONE znAFMtr).
4+
5+
Air flow is recorded in standard air cfm (density 0.075 lb/ft3) at subhour, hour, day, month, and year durations. Flows are categorized according to IZXFER izAFCat.
6+
7+
Note that *only* AirNet flows are recorded.
8+
9+
10+
**afMtrName**
11+
12+
Name of meter: required for assigning energy uses to the meter elsewhere.
13+
14+
**Units** **Legal Range** **Default** **Required** **Variability**
15+
----------- ----------------- ------------- -------------- -----------------
16+
*63 characters* *none* Yes constant
17+
18+
**endAFMeter**
19+
20+
Indicates the end of the meter definition. Alternatively, the end of the meter definition can be indicated by the declaration of another object or by END.
21+
22+
**Units** **Legal Range** **Default** **Required** **Variability**
23+
----------- ----------------- ------------- -------------- -----------------
24+
*N/A* No constant
25+
26+
**Related Probes:**
27+
28+
- @[afmeter](#p_afmeter)

doc/src/records/izxfer.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,36 @@ Choice determining interzone ventilation
7676

7777
-----------------------------------------------------------------
7878

79+
**izAFCat=*choice***
80+
81+
Choice indicating air flow category used *only* for recording air flow results to an AFMETER. izAFCat has no effect for non-AIRNET IZXFERs. izAFCat is not used unless the associated ZONE(s) specify znAFMtr.
82+
83+
84+
Choices are:
85+
86+
---------- -------------------------------------------
87+
InfilEx Infiltration from ambient
88+
VentEx Natural ventilation from ambient
89+
FanEx Forced ventilation from ambient
90+
InfilIz Interzone infiltration
91+
VentIz Interzone natural ventilation
92+
FanIz Interzone forced ventilation
93+
DuctLk Duct leakage
94+
HVAC HVAC air
95+
--------- -------------------------------------------
96+
97+
Default values for izAFCat are generally adequate *except* that natural ventilation IZXFERs are by default categorized as infiltration. It is thus recommended that izAfCat be omitted except that ventilation IZXFERs (e.g. representing openable windows) should include izAfCat=VentEx (or VentIz).
98+
99+
----------------------------------------------------------------
100+
**Units** **Legal** **Default** **Required** **Variability**
101+
**Range**
102+
--------- --------------- ------------------------------------- ------------- ---------------
103+
*choices above* derived from IZXFER characteristics No constant
104+
105+
-----------------------------------------------------------------
106+
107+
108+
79109
**izZn1=*znName***
80110

81111
Name of primary zone. Flow rates $>$ 0 are into the primary zone.

doc/src/records/report.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ Choice indicating report type. Report types may be described at greater length,
9494

9595
DHWMTR DHW meter report. Requires *rpDHWMeter*
9696

97+
AFMTR Air flow meter report. Requires *rpAFMeter*
98+
9799
<% if inactive_CNE_records %>
98100
AH Air handler report. Requires *rpAh*.
99101

@@ -202,6 +204,15 @@ Specifies DHW meter(s) to be reported, for *rpType*=DHWMTR.
202204
--------- ------------------------------ ------------- ---------------------------- ---------------
203205
name of a *DHWMETER*, ALL, SUM Required for *rpType*=DHWMTR constant
204206

207+
**rpAFMeter=*afMtrName***
208+
209+
Specifies air flow meter(s) to be reported, for *rpType*=AFMTR.
210+
211+
**Units** **Legal Range** **Default** **Required** **Variability**
212+
--------- ------------------------------ ------------- ---------------------------- ---------------
213+
name of a *DHWMETER*, ALL, SUM Required for *rpType*=AFMTR constant
214+
215+
205216
<% if inactive_CNE_records %>
206217
**rpAh=*ahName***
207218

doc/src/records/zone.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,22 @@ Number of stories in zone, used in ELA model.
279279
----------- ----------------------- ------------- -------------- -----------------
280280
1 $\leq$ *x* $\leq$ 3 1 No constant
281281

282-
**znWindFLkg=*floatTODO***
282+
**znWindFLkg=*float***
283+
284+
Wind speed modifier factor. The weather file wind speed is multiplied by this factor to yield a local wind speed for use in infiltration and convection models.
285+
286+
**Units** **Legal Range** **Default** **Required** **Variability**
287+
----------- ----------------- ------------------------------------ -------------- -----------------
288+
$\geq$ 0 derived from zn_eaveZ and infShld No constant
289+
290+
**znAFMtr=*afMtrName***
291+
292+
Name of AFMETER object, if any, to which zone AirNet air flows are recorded. *ZnAFMtr* defines a pressure boundary for accounting purposes. Multiple zones having the same AFMETER are treated as a single volume -- interzone flows within that volume are not recorded. For example, to obtain "building total" flow data, a common AFMETER could be assigned to several conditioned zones but not to adjacent unconditioned zones such as attic spaces.
293+
294+
**Units** **Legal Range** **Default** **Required** **Variability**
295+
----------- --------------------- ---------------- -------------- -----------------
296+
*name of an AFMETER* *not recorded* No constant
283297

284-
**Units** **Legal Range** **Default** **Required** **Variability**
285-
----------- ----------------- ------------- -------------- -----------------
286-
1 No constant
287298

288299
## ZONE Exhaust Fan
289300

src/CGCOMP.CPP

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,8 @@ static float fShield[ 5][ 2] =
232232
// within two house heights
233233
};
234234

235-
#if 1 // insurance, 11-18-2014
236235
if (Z <= 0.f)
237236
return 0.f;
238-
#endif
239237

240238
float SC = fShield[ bracket( 1, shieldClass, 5)-1][ 1];
241239
if (terrainClass <= 0)
@@ -339,17 +337,15 @@ void AFMTR::amt_Accum(
339337
// ASSUMES interval members ordered like DTIVLCH choices
340338
AFMTR_IVL* sIvl0 = amt_GetAFMTR_IVL(ivl + 1); // source: next shorter interval
341339

342-
int options = 0; // default: track average
343-
344-
if (ivl == C_IVLCH_Y)
345-
options = 1; // average by day for non-sum-of year values
346-
// handles diffs due to month length
340+
int options =
341+
ivl == C_IVLCH_Y ? 1 // average by day for non-sum-of year values
342+
// handles diffs due to month length
343+
: 0; // default: track average
347344
for (int iPN=0; iPN<2; iPN++)
348345
dIvl0[ iPN].amt_Accum(sIvl0+iPN, firstFlg, lastFlg, options);
349346

350347
if (lastFlg)
351-
{
352-
AFMTR* pAMSum = AfMtrR.p + AfMtrR.n;
348+
{ AFMTR* pAMSum = AfMtrR.p + AfMtrR.n;
353349
AFMTR_IVL* dIvlSum0 = pAMSum->amt_GetAFMTR_IVL( ivl);
354350
for (int iPN = 0; iPN < 2; iPN++)
355351
dIvlSum0[ iPN].amt_Accum(dIvl0+iPN, ss == 1, 0);
@@ -1050,13 +1046,13 @@ x }
10501046
void IZXRAT::iz_SetupAfMtrs()
10511047
{
10521048
// Air flow category
1053-
if (iz_afCat == 0)
1054-
iz_afCat = iz_AfCatDefault();
1049+
if (!IsSet(IZXRAT_AFCAT))
1050+
iz_afCat = iz_AfCatDefault(); // default category (may return -1)
10551051

10561052
// AFMTR ptrs: NULL if no meter specified -> no air flow accounting
10571053
// one pointer for positive flows, one for negative
10581054
iz_pAfMtr1 = iz_pAfMtr2 = NULL; // insurance
1059-
if (iz_afCat > 0)
1055+
if (iz_afCat >= 0)
10601056
{ // set up ptrs to AFMTR(s)
10611057
const ZNR* zp;
10621058
if (iz_zi1 > 0)
@@ -1067,9 +1063,10 @@ void IZXRAT::iz_SetupAfMtrs()
10671063
{ // interzone transfers recorded iff to a different meter
10681064
zp = ZrB.GetAt(iz_zi2);
10691065
AFMTR* pAM = AfMtrR.GetAtSafe(zp->i.zn_afMtri);
1070-
if (pAM == iz_pAfMtr1)
1066+
if (pAM == iz_pAfMtr1 && !iz_IsHERV())
10711067
iz_pAfMtr1 = NULL; // same meter on both sides of IZ
10721068
// don't record IZ within meter
1069+
// EXCEPT for HERV
10731070
else
10741071
iz_pAfMtr2 = pAM; // z2 meter specified and differs from z1
10751072
}
@@ -1082,24 +1079,18 @@ void IZXRAT::iz_SetupAfMtrs()
10821079
AFCAT IZXRAT::iz_AfCatDefault() const
10831080
{
10841081
AFCAT afCat;
1085-
if (iz_IsSysAir())
1082+
if (!iz_IsAirNet())
1083+
afCat = -1; // track only airnet flows
1084+
else if (iz_IsSysAir())
10861085
afCat = C_AFCAT_HVAC;
10871086
else if (iz_IsDuctLk())
10881087
afCat = C_AFCAT_DUCTLK;
1088+
else if (iz_IsHERV())
1089+
afCat = iz_IsHERVIZ() ? C_AFCAT_FANIZ : C_AFCAT_FANEX;
10891090
else if (iz_IsExterior())
1090-
{ if (iz_IsFixedFlow())
1091-
afCat = C_AFCAT_FANEX;
1092-
else
1093-
afCat = C_AFCAT_INFILEX;
1094-
}
1091+
afCat = iz_IsFixedFlow() ? C_AFCAT_FANEX : C_AFCAT_INFILEX;
10951092
else
1096-
{ if (iz_IsFixedFlow())
1097-
afCat = C_AFCAT_FANIZ;
1098-
else if (iz_IsAirNet())
1099-
afCat = C_AFCAT_INFILIZ;
1100-
else
1101-
afCat = 0;
1102-
}
1093+
afCat = iz_IsFixedFlow() ? C_AFCAT_FANIZ : C_AFCAT_INFILIZ;
11031094

11041095
return afCat;
11051096

@@ -1536,7 +1527,7 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
15361527
}
15371528

15381529
// air flow accounting
1539-
iz_amfNom // nominal flow, lbm/sec
1530+
iz_amfNom // incoming nominal flow, lbm/sec
15401531
= (1.f - fVent)*iz_ad[0].ad_mdotP + fVent * iz_ad[1].ad_mdotP;
15411532
if (iz_nvcntrl == C_IZNVTYCH_ANHORIZ)
15421533
iz_amfNom
@@ -1545,8 +1536,12 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
15451536
{ if (iz_pAfMtr1)
15461537
iz_pAfMtr1->amt_AccumCat(iz_afCat, iz_amfNom);
15471538
if (iz_pAfMtr2)
1548-
// flow is opposite direction from z2 POV
1549-
iz_pAfMtr2->amt_AccumCat(iz_afCat, -iz_amfNom);
1539+
{ // flow is opposite direction from z2 POV
1540+
// HERV: iz_pAfMtr2 points to exhaust source zone (may be z1)
1541+
// HERV same for vent / no vent (use iz_ad[ 0] w/o fVent)
1542+
iz_pAfMtr2->amt_AccumCat(iz_afCat,
1543+
iz_IsHERV() ? -iz_ad[0].ad_mdotX : -iz_amfNom);
1544+
}
15501545
}
15511546

15521547
return RCOK;
@@ -1696,6 +1691,8 @@ RC AIRNET::an_Calc( // airnet flow balance
16961691
for (zi=0; zi < an_nz; zi++)
16971692
{ // Net mass flow to each zone s/b 0
16981693
// Solution not converged if netAMF > max( ResAbs, totAMF*ResRel)
1694+
// Using larger of the two tolerances means zones with small abs flow converge loosely.
1695+
// This avoids extra iterations to converge zones that have minor impact.
16991696
if (fabs( rV[ zi]) > ResAbs && fabs( rV[ zi]) > ResRel*an_mdotAbs[ zi])
17001697
{ bConverge = FALSE;
17011698
break; // this zone not balanced, no need to check further

src/CGRESULT.CPP

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -258,17 +258,17 @@ static COLDEF afMtrColdef[] =
258258
{ "FanZ+", 0, 5, D, oAFMt0(amt_fanIz), CV1 },
259259
{ "Duct+", 0, 5, D, oAFMt0(amt_ductLk), CV1 },
260260
{ "HVAC+", 0, 5, D, oAFMt0(amt_hvac), CV1 },
261-
{ "Tot-", 0, 5, D, oAFMt1(amt_total), CV1 },
262-
{ "Unkn-", 0, 5, D, oAFMt1(amt_unknown),CV1 },
263-
{ "InfX-", 0, 5, D, oAFMt1(amt_infilEx),CV1 },
264-
{ "VntX-", 0, 5, D, oAFMt1(amt_ventEx), CV1 },
265-
{ "FanX-", 0, 5, D, oAFMt1(amt_fanEx), CV1 },
266-
{ "InfZ-", 0, 5, D, oAFMt1(amt_infilIz),CV1 },
267-
{ "VntZ-", 0, 5, D, oAFMt1(amt_ventIz), CV1 },
268-
{ "FanZ-", 0, 5, D, oAFMt1(amt_fanIz), CV1 },
269-
{ "Duct-", 0, 5, D, oAFMt1(amt_ductLk), CV1 },
270-
{ "HVAC-", 0, 5, D, oAFMt1(amt_hvac), CV1 },
271-
{ 0, 0, 0, 0, 0, CV1 }
261+
{ "Tot-", 0, 6, D, oAFMt1(amt_total), CV1 },
262+
{ "Unkn-", 0, 6, D, oAFMt1(amt_unknown),CV1 },
263+
{ "InfX-", 0, 6, D, oAFMt1(amt_infilEx),CV1 },
264+
{ "VntX-", 0, 6, D, oAFMt1(amt_ventEx), CV1 },
265+
{ "FanX-", 0, 6, D, oAFMt1(amt_fanEx), CV1 },
266+
{ "InfZ-", 0, 6, D, oAFMt1(amt_infilIz),CV1 },
267+
{ "VntZ-", 0, 6, D, oAFMt1(amt_ventIz), CV1 },
268+
{ "FanZ-", 0, 6, D, oAFMt1(amt_fanIz), CV1 },
269+
{ "Duct-", 0, 6, D, oAFMt1(amt_ductLk), CV1 },
270+
{ "HVAC-", 0, 6, D, oAFMt1(amt_hvac), CV1 },
271+
{ 0, 0, 0, 0, 0, CV1 }
272272
};
273273
#undef D
274274
#undef oAFMt0
@@ -552,19 +552,18 @@ o vpRxFooter(dvrip); // do the footer, below. clears VR_NEEDFOOT.
552552
void FC vpRxports( // virtual print reports and exports of given frequency for current interval
553553

554554
IVLCH freq, // interval desired: C_IVLCH_Y, M, D, H, S.
555-
// HS generated internally when H or S given. HS cannot be given by caller.
556-
BOO auszOnly/*=FALSE*/ ) /* non-0 to do ONLY autosizing results reports (AHSIZE, TUSIZE).
557-
used after autosize when main sim will not be performed.
558-
Experiment 5-97 to fix oversight in original ausz implementation;
559-
possibly autosize results reports should always be (have been) done this way
560-
(always call after autosize, then exclude then when auszOnly FALSE). */
555+
// HS generated internally when H or S given. HS cannot be given by caller.
556+
BOO auszOnly/*=FALSE*/ ) // non-0 to do ONLY autosizing results reports (AHSIZE, TUSIZE).
557+
// used after autosize when main sim will not be performed.
558+
// Experiment 5-97 to fix oversight in original ausz implementation;
559+
// possibly autosize results reports should always be (have been) done this way
560+
// (always call after autosize, then exclude then when auszOnly FALSE). */
561561
{
562-
SI i;
563-
SI reHead = 0; // set non-0 to print report title & col heads even if not 1st time
564-
SI doFoot = 0; // non-0 for report end: blank line, Yr summary, etc
562+
int reHead = 0; // set non-0 to print report title & col heads even if not 1st time
563+
int doFoot = 0; // non-0 for report end: blank line, Yr summary, etc
565564
RXPORTINFO rxt; // much info to pass to/amoung callees
566565

567-
memset( &rxt, 0, sizeof(rxt)); // default all info members to 0
566+
memset( &rxt, 0, sizeof(rxt)); // default all info members to 0
568567
rxt.fqr = rxt.fq = freq; // store args
569568

570569
// init by frequency; each case breaks; stuff used by more than one report type
@@ -602,7 +601,6 @@ void FC vpRxports( // virtual print reports and exports of given frequency for
602601

603602
switch (rxt.fq)
604603
{
605-
/*lint -e616 cases fall thru */
606604
case C_IVLCH_S:
607605
rxt.xebS[0] = 'a' + (char)Top.iSubhr; // ZEB export subhour: leave "" if not subhourly
608606
case C_IVLCH_H:
@@ -613,32 +611,28 @@ void FC vpRxports( // virtual print reports and exports of given frequency for
613611
rxt.xebM = Top.tp_date.month;
614612
case C_IVLCH_Y:
615613
;
616-
default: ; /*lint +e616 */
614+
default: ;
617615
}
618616

619617
// loop over reports active for given frequency
620618

621619
for ( ; ; ) // repeats to do HS if rpfreq==H or S.
622-
{
623-
DVRI *dvrip /*=NULL*/;
624-
RPTYCH rpTy;
625-
SI vrh, isAll, isExport;
626-
627-
for (i = (&Top.dvriY)[rxt.fq-1]; i; i = dvrip->nextNow) // loop over DvriB records in list for interval
620+
{ DVRI *dvrip /*=NULL*/;
621+
for (int i = (&Top.dvriY)[rxt.fq-1]; i; i = dvrip->nextNow) // loop over DvriB records in list for interval
628622
{
629623
dvrip = DvriB.p + i; // point Date-dependent Virtual Report Info record
630-
rpTy = dvrip->rpTy; // fetch report type
631-
vrh = dvrip->vrh; // fetch output destination
632-
isExport = dvrip->isExport; // true if export (not report)
633-
isAll = dvrip->isAll; // true if zi or mtri or ... is TI_ALL
624+
RPTYCH rpTy = dvrip->rpTy; // fetch report type
625+
int vrh = dvrip->vrh; // fetch output destination
626+
int isExport = dvrip->isExport; // true if export (not report)
627+
int isAll = dvrip->isAll; // true if zi or mtri or ... is TI_ALL
634628
rxt.flags = (rxt.flags &~(4|2)) | (isExport ? 4 : 2); // set export (4) or report (2) flag bit; clear prior.
635629
rxt.flags = (rxt.flags &~(16|8)) // set name (16) & time (8) col flags r/xport
636630
| ( isExport ? (16|8) // exports show BOTH name and the 4 export time columns
637631
: (isAll ? 16 : 8) ); // all- reports show name, others rpts show time column
638-
rxt.flags = (rxt.flags &~(64|32)) // include shutter frac * (64) and Mode (32) columns
632+
rxt.flags = (rxt.flags &~(64|32)) // include shutter frac * (64) and Mode (32) columns
639633
| ( rxt.fq >= C_IVLCH_S // .. in _HS and _S reports
640634
&& (dvrip->ownTi > 0 || isAll ) // .. for a single zone or all zones
641-
|| isExport // .. and in all exports (keep format constant)
635+
|| isExport // .. and in all exports (keep format constant)
642636
? (64|32) : 0 ); // (but data is blanked/0'd below in non-subhr lines)
643637

644638
// footer line: also on last day of day, month, or year report
@@ -836,8 +830,8 @@ o vpRxFooter(dvrip); // virtual print report or export footer, below. c
836830

837831
} // for i=
838832

839-
/* if hourly or subhourly specified, repeat for hourly+subhourly: hourly+subhourly reports are in a separate list
840-
as there is only one .nextNow in DVRI. */
833+
// if hourly or subhourly specified, repeat for hourly+subhourly
834+
// hourly+subhourly reports are in a separate list as there is only one .nextNow in DVRI.
841835
if (rxt.fq==C_IVLCH_H) // if caller said do hour hourly lines
842836
{ rxt.fq = C_IVLCH_HS; // do the hourly lines of the HS reports/exports too
843837
reHead = 0; // no header at hrly line of HS's: header happened at subHour 0.
@@ -1501,7 +1495,9 @@ void DVRI::dv_vpAfMtrRow(RXPORTINFO *rxt, TI afMtri /*=-1*/)
15011495
if (afMtri == TI_SUM)
15021496
afMtri = AfMtrR.n; // handle "sum"
15031497
AFMTR* pM = AfMtrR.GetAt(afMtri); // record
1504-
AFMTR_IVL* pIvl = pM->amt_GetAFMTR_IVL( rxt->fq); // interval
1498+
AFMTR_IVL* pIvl = pM->amt_GetAFMTR_IVL( rxt->fqr); // interval
1499+
// results substr offset from .Y: M, D, H, S follow .Y, no HS.
1500+
// .fqr is H or S when .fq is HS for hourly+subhourly reports
15051501
15061502
vpRxRow(this, rxt, pIvl, rxt->col1, pM->name, &rxt->xebM, &rxt->xebD, &rxt->xebH, rxt->xebS);
15071503
} // dv_vpDHWMtrRow

src/CNCULT.CPP

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@ CULT( "izZn1", DAT, IZXRAT_ZI1, RQD, 0, VEOI, TYREF, &ZiB, 0.f,
15331533
CULT( "izZn2", DAT, IZXRAT_ZI2, 0, 0, VEOI, TYREF, &ZiB, 0.f, N, N),
15341534
CULT( "izHConst", DAT, IZXRAT_UA, 0, 0, VHRLY, TYFL, 0, 0.f, N, N),
15351535
CULT( "izNVType", DAT, IZXRAT_NVCNTRL,0, 0, VEOI, TYCH, 0, C_IZNVTYCH_NONE, N, N),
1536-
CULT( "izAFCat", DAT, IZXRAT_AFCAT, 0, 0, VEOI, TYCH, 0, 0, N, N),
1536+
CULT( "izAFCat", DAT, IZXRAT_AFCAT, 0, 0, VEOI, TYCH, 0, -1, N, N),
15371537
CULT( "izALo", DAT, IZXRAT_A1, 0, 0, VHRLY, TYFL, 0, 0.f, N, N),
15381538
CULT( "izAHi", DAT, IZXRAT_A2, 0, 0, VHRLY, TYFL, 0, 0.f, N, N),
15391539
CULT( "izL1", DAT, IZXRAT_L1, 0, 0, VEOI, TYFL, 0, 0.f, N, N),

0 commit comments

Comments
 (0)