Skip to content

Commit 53f4063

Browse files
authored
Merge pull request #106 from cse-sim/reportinfil
Air flow accounting and reporting
2 parents 7ce1c66 + 203e5fe commit 53f4063

38 files changed

+8452
-7927
lines changed

src/ANCREC.CPP

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -592,14 +592,18 @@ RC FC basAnc::free() // free (non-static) record memory block for anchor
592592
return RCOK;
593593
} // basAnc::free
594594
//---------------------------------------------------------------------------------------------------------------------------
595-
RC basAnc::add( record **_r, int erOp, TI i/*=0*/) // construct record i (0 = next). Allocs if nec.
595+
RC basAnc::add( // construct record i (0 = next). Allocs if nec.
596+
record **_r, // returned: ptr to add record
597+
int erOp, // error handling
598+
TI i/*=0*/, // where to add
599+
const char* _name /*=NULL*/) // optional name for added record
596600
{
597601
#ifdef DEBUG2
598-
if (validate("basAnc::add", erOp)) return RCBAD; // check anchor
602+
if (validate("basAnc::add", erOp)) // check anchor
603+
return RCBAD;
599604
#endif
600605
if (!i) // if we are to choose record number
601-
{
602-
i = mn; // 1: record # 0 is not used
606+
{ i = mn; // 1: record # 0 is not used
603607
if (ptr())
604608
{
605609
while (i <= n && rec(i).gud) i++; // find record space with gud==0 else 1 more than last used.
@@ -611,15 +615,14 @@ RC basAnc::add( record **_r, int erOp, TI i/*=0*/) // construct record i (0 = ne
611615
|| !ptr() ) // insurance
612616
{
613617
ULI sz = (ULI)nAl*eSz + 1024; // new size in bytes to add 1 + 1K's worth of record spaces (nAl is +1)
614-
#if 0 // eliminate 64K limit, 9-10
615-
x setToMin( sz, 0x0000FFF0UL); // don't go over 64K to get the 1K+1. Allow a few overhead bytes.
616-
#endif
617618
register TI _n = max( (USI)(sz/eSz), (USI)i); // add 1 + 1K's worth of spaces, or to req'd rec # if more.
618619
if (reAl(_n, erOp))
619620
return RCBAD; // (re)alloc rec spaces 1.._n, init nAl, ptr(), space[0], etc. above.
620621
}
621622
conRec(i); // construct record i: mark in use, zero, init std base members, do specific record init.
622623
*_r = &rec(i); // return pointer to the added record
624+
if (_name)
625+
(*_r)->SetName(_name);
623626
if (i > n)
624627
n = i; // increase max in-use subscript (loop limit) to that just allocated
625628
return RCOK; // error returns above
@@ -638,7 +641,7 @@ RC FC basAnc::del( TI i, int erOp/*=ABT*/) // delete (squeeze out) ith record
638641
{
639642
if (!dest.gud)
640643
conRec(i); // construct destination if nec to insure vftp, rt, b, ss set.
641-
dest.CopyFrom(&src); // copy record i+1 to i without dup'ing heap ptrs
644+
dest.CopyFrom(&src); // copy record i+1 to i without dup'ing heap ptrs
642645
// tentatively no destroy: does nothing in base class, and deriv class might delete heap ptrs we did not dup.
643646
#if defined( _DEBUG)
644647
dest.Validate();

src/ANCREC.H

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ class basAnc // base class for record anchors: basAnc<recordName>
8686
BP ownB; // 0 or ptr to anchor whose objects own this anchor's objects (record.ownTi)
8787
const CULT* an_pCULT; // NULL or associated CULT input table for records of this type
8888
// simplifies back translation of input names
89-
9089
basAnc();
9190
basAnc( int flags, SFIR * fir, USI nFlds, char * what, USI eSz, RCT rt, USI sOff, int dontRegister=0 );
9291
void FC regis();
@@ -101,7 +100,7 @@ class basAnc // base class for record anchors: basAnc<recordName>
101100
RC FC al( TI n, int erOp=ABT, BP _ownB=NULL); // allocate records block. destroys old recs.
102101
RC FC reAl( TI n, int erOp=ABT); // (re)allocate records block. keeps old recs <= n.
103102
RC FC free(); // free block
104-
RC add( record **r, int erOp, TI i=0); // add record to block
103+
RC add( record **r, int erOp, TI i=0, const char* _name=NULL); // add record to block
105104
RC FC del( TI i, int erOp=ABT); // delete record i
106105
void statSetup( record &r, TI n=1, SI noZ=0, SI inHeap=0); // set up with static record(s)
107106
int isNamed() const { return ba_flags & RFNAMED; } // records have .name[]: always on, coding out 7-92
@@ -308,8 +307,9 @@ template <class T> class anc : public basAnc
308307
virtual void setPtr( record* r) { p = (T*)r; }
309308
virtual record& rec(TI i) { return p[i]; } // access record i in base/generic code
310309
virtual void * recMbr(TI i, USI off) { return (void *)((char *)(p + i) + off); } // point record i member by offset
311-
RC add( T **r, int erOp, TI i = 0) { return basAnc::add((record * *)r, erOp, i); }
312-
RC RunDup( const anc< T> &src, BP _ownB=NULL, int erOp=ABT);
310+
RC add( T **r, int erOp, TI i = 0, const char* name=NULL)
311+
{ return basAnc::add((record **)r, erOp, i, name); }
312+
RC RunDup( const anc< T> &src, BP _ownB=NULL, int nxRecs=0, int erOp=ABT);
313313
RC AllocResultsRecs(basAnc& src);
314314
void statSetup( T &r, TI n=1, SI noZ=0, SI inHeap=0) { basAnc::statSetup( r, n, noZ, inHeap); }
315315
int GetCount( int options=0) const;
@@ -421,6 +421,8 @@ template <class T> int anc<T>::GetCount( int options /*=0*/) const
421421
template <class T> RC anc<T>::RunDup( // duplicate records for run
422422
const anc<T> &src, // source array (e.g. input data)
423423
BP _ownB /*= NULL*/, // owner (if any)
424+
int nxRecs /*=0*/, // # of extra run records to allocate
425+
// (e.g. for "sum-of-all")
424426
int erOp /*=ABT*/) // error action re alloc fail
425427
// typically ABT, no remedy
426428
// typical use = input -> run
@@ -429,7 +431,7 @@ template <class T> RC anc<T>::RunDup( // duplicate records for run
429431
// allows record-level run cancel
430432
{
431433
// delete old records, alloc to needed size for min fragmentation
432-
RC rc = al(src.n, erOp, _ownB);
434+
RC rc = al(src.n+nxRecs, erOp, _ownB);
433435

434436
an_pCULT = src.an_pCULT; // assume same associated CULT
435437

src/CGCOMP.CPP

Lines changed: 138 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,76 @@ float TOPRAT::tp_WindPresV( // wind velocity pressure
257257
} // TOPRAT::tp_WindPresV
258258
//===============================================================================
259259

260+
///////////////////////////////////////////////////////////////////////////////
261+
// AFMTR_IVL, AFMTR: accumulates air mass flow by category
262+
///////////////////////////////////////////////////////////////////////////////
263+
/*static*/ const int AFMTR_IVL::NAFCATS
264+
= (sizeof(AFMTR_IVL) - offsetof( AFMTR_IVL, amt_total)) / sizeof(float);
265+
// NAFCATS s/b same as AFCAT choices + 1 (for total)
266+
static_assert(AFMTR_IVL::NAFCATS == C_AFCAT_COUNT+1, "Inconsistent AFMTR constants");
267+
//-----------------------------------------------------------------------------
268+
void AFMTR_IVL::amt_Copy(
269+
const AFMTR_IVL* s)
270+
{
271+
memcpy(this, s, sizeof(AFMTR_IVL));
272+
} // AFMTR_IVL::amt_Copy
273+
//-----------------------------------------------------------------------------
274+
void AFMTR_IVL::amt_Accum( // accumulate
275+
const AFMTR_IVL* sIvl, // source
276+
int firstFlg, // true iff first accum into this (beg of ivl)
277+
int lastFlg) // true iff last accum into this (end of ivl)
278+
279+
{
280+
if (firstFlg)
281+
{ amt_Copy(sIvl);
282+
amt_count = 1;
283+
}
284+
else
285+
{ VAccum(&amt_total, NAFCATS, &sIvl->amt_total);
286+
amt_count++;
287+
}
288+
if (lastFlg)
289+
VMul1(&amt_total, NAFCATS, 1.f / amt_count);
290+
} // AFMTR_IVL
291+
//-----------------------------------------------------------------------------
292+
RC AFMTR::amt_CkF()
293+
{
294+
return RCOK;
295+
}
296+
//-----------------------------------------------------------------------------
297+
RC AFMTR::amt_BegSubhr() // init at beg of subhr
298+
{
299+
S.amt_Clear();
300+
return RCOK;
301+
} // AFMTR::amt_BegSubhr
302+
//-----------------------------------------------------------------------------
303+
void AFMTR::amt_AccumCat( // accumulate air flow value for current subhour
304+
AFCAT afCat, // air flow category
305+
float amf) // air mass flow, lbm/sec
306+
{
307+
if (amf > 0.f) // record only flow into zone
308+
{ // convert lbm/s -> cfm std air
309+
S.amt_AccumCat(afCat, AMFtoAVF2( amf));
310+
}
311+
} // AFMTR::amt_AccumCat
312+
//-----------------------------------------------------------------------------
313+
void AFMTR::amt_Accum(
314+
IVLCH ivl, // destination interval: hour/day/month/year
315+
// Accumulates from subhour/day/month. Not Top.ivl!
316+
int firstFlg, // iff TRUE, destination will be initialized before values are accumulated into it
317+
int lastFlg) // iff TRUE, destination averages will be computed as needed
318+
{
319+
AFMTR_IVL* dIvl = &Y + (ivl - C_IVLCH_Y); // point destination substruct for interval
320+
// ASSUMES interval members ordered like DTIVLCH choices
321+
AFMTR_IVL* sIvl = dIvl + 1; // source: next shorter interval
322+
323+
// accumulate: copy on first call (in lieu of 0'ing dIvl).
324+
// Note: amt_Init() call in doBegIvl 0s H values
325+
dIvl->amt_Accum(sIvl, firstFlg, lastFlg);
326+
} // AFMTR::amt_Accum
327+
//=============================================================================
328+
329+
260330
/////////////////////////////////////////////////////////////////////////////////
261331
// AIRSTATE
262332
/////////////////////////////////////////////////////////////////////////////////
@@ -704,8 +774,7 @@ RC IZXRAT::iz_SetupHERV() // set mbrs re HERV model
704774
DbPrintf( "HERV '%s' in: avf=%.2f rho=%.5f mdotP=%.5f\n out: avf=%.2f rho=%.5f mdotP=%.5f\n",
705775
name, avfGross, iz_rho2, ad.ad_mdotP, avfGross*iz_vfExhRat, rhoX, ad.ad_mdotX);
706776
#endif
707-
708-
777+
709778
// iz_air2 / iz_rho2 = air state into z1
710779
// Note: calc HX with moist air mass flow rates
711780
// some sources say dry AMF, not fully understood
@@ -951,9 +1020,54 @@ x }
9511020

9521021
iz_SetupNonAirNet(); // calc izxfer derived values
9531022

1023+
iz_SetupAfMtrs(); // AFMETER (air flow meter) setup
1024+
9541025
return rc;
955-
} // IZXRAT::iz_Setup()
1026+
} // IZXRAT::iz_Setup
9561027
#undef ZFAN
1028+
//-------------------------------------------------------------------
1029+
void IZXRAT::iz_SetupAfMtrs()
1030+
{
1031+
// Air flow category
1032+
if (iz_afCat == 0)
1033+
iz_afCat = iz_AfCatDefault();
1034+
1035+
// AFMTR ptrs: NULL if no meter specified -> no air flow accounting
1036+
// one pointer for positive flows, one for negative
1037+
const ZNR* zp;
1038+
if (iz_zi1 > 0)
1039+
{ zp = ZrB.GetAt(iz_zi1);
1040+
iz_pPosAfMtr = AfMtrR.GetAtSafe(zp->i.zn_afMtri);
1041+
}
1042+
if (iz_zi2 > 0)
1043+
{ zp = ZrB.GetAt(iz_zi2);
1044+
iz_pNegAfMtr = AfMtrR.GetAtSafe(zp->i.zn_afMtri);
1045+
}
1046+
} // IZXRAT::iz_SetupAfMtrs
1047+
//-----------------------------------------------------------------------------
1048+
AFCAT IZXRAT::iz_AfCatDefault() const
1049+
{
1050+
AFCAT afCat;
1051+
if (iz_IsSysAir())
1052+
afCat = C_AFCAT_HVAC;
1053+
else if (iz_IsDuctLk())
1054+
afCat = C_AFCAT_DUCTLK;
1055+
else if (iz_IsExterior())
1056+
{ if (iz_IsFixedFlow())
1057+
afCat = C_AFCAT_FANEX;
1058+
else
1059+
afCat = C_AFCAT_INFILEX;
1060+
}
1061+
else
1062+
{ if (iz_IsFixedFlow())
1063+
afCat = C_AFCAT_FANIZ;
1064+
else
1065+
afCat = C_AFCAT_INFILIZ;
1066+
}
1067+
1068+
return afCat;
1069+
1070+
} // IZXRAT::iz_AfcatDefault
9571071
//-----------------------------------------------------------------------------
9581072
RC IZXRAT::iz_SetupNonAirNet() // interzone transfer one-time initialization
9591073

@@ -1096,6 +1210,8 @@ TI ZNR::zn_AddIZXFER( // add IZXFER coupled to this zone
10961210
else
10971211
ize->iz_zi2 = -1; // no other zone
10981212

1213+
ize->iz_SetupAfMtrs(); // default iz_afCat, set up AFMTR linkage
1214+
10991215
// more init?
11001216

11011217
return ize->ss;
@@ -1255,7 +1371,6 @@ RC IZXRAT::iz_Calc()
12551371
ZNR* zp1 = ZrB.GetAt( iz_zi1);
12561372
ZNR* zp2 = ZrB.GetAt( iz_zi2);
12571373
float tdif = zp1->tzls - zp2->tzls; // temp diff between zones
1258-
#if 1
12591374
if (iz_nvcntrl != C_IZNVTYCH_ONEWAY || tdif > 0.f)
12601375
{ double hx = iz_ua;
12611376
if (iz_nvcntrl != C_IZNVTYCH_NONE)
@@ -1264,15 +1379,6 @@ RC IZXRAT::iz_Calc()
12641379
zp1->zn_qIzXAnSh -= qx; // accumulate heat/hour to zone
12651380
zp2->zn_qIzXAnSh += qx; // same for other zone, opposite sign: positive into zone.
12661381
}
1267-
#else
1268-
x float hx = iz_ua; // coupling coeff: init to constant (conduction) portion
1269-
x if (iz_nvcntrl==C_IZNVTYCH_TWOWAY) // if nat vent tween zones
1270-
x hx += iz_nvcoeff * sqrt( fabs( tdif)); // it is proportional to sqrt temp difference
1271-
x float qx = hx * tdif; // heat xfer per hour (power): coupling * temp diff.
1272-
x // positive for xfer from zn1 to zn2
1273-
x zp1->zn_qIzXAnSh -= qx; // accumulate heat/hour to zone
1274-
x zp2->zn_qIzXAnSh += qx; // same for other zone, opposite sign: positive into zone.
1275-
#endif
12761382
return RCOK;
12771383
} // IZXRAT::iz_Calc
12781384
//--------------------------------------------------------------------------------
@@ -1380,7 +1486,6 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
13801486
{
13811487
ZNR* zp = ZrB.GetAt( iz_zi1); // zone
13821488
float fVent = zp->zn_fVent;
1383-
iz_amfNom = (1.f-fVent)*iz_ad[ 0].ad_mdotP + fVent*iz_ad[ 1].ad_mdotP;
13841489
if (iz_HasFan() && iz_fan.fn_mtri)
13851490
{ // calc fan electricity and accum to meter
13861491
// need venting fraction to determine fan operation
@@ -1393,18 +1498,34 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
13931498
iz_fan.fn_endUse, // user-specified end use (default = "fan")
13941499
fanPwr * Top.subhrDur); // electrical energy, Btu (*not* Wh)
13951500
}
1501+
1502+
// air flow accounting
1503+
iz_amfNom // nominal flow, lbm/sec
1504+
= (1.f - fVent)*iz_ad[0].ad_mdotP + fVent * iz_ad[1].ad_mdotP;
1505+
if (iz_nvcntrl == C_IZNVTYCH_ANHORIZ)
1506+
iz_amfNom
1507+
+= (1.f - fVent)*iz_ad[0].ad_mdotB + fVent * iz_ad[1].ad_mdotB;
1508+
if (iz_amfNom > 0.f)
1509+
{ if (iz_pPosAfMtr)
1510+
iz_pPosAfMtr->amt_AccumCat(iz_afCat, iz_amfNom);
1511+
}
1512+
else if (iz_amfNom < 0.f)
1513+
{ // flow is out of zn1 = into zn2
1514+
if (iz_pNegAfMtr)
1515+
iz_pNegAfMtr->amt_AccumCat(iz_afCat, -iz_amfNom);
1516+
}
1517+
13961518
return RCOK;
13971519
} // IZXRAT::iz_EndSubhr
1398-
13991520
//=============================================================================
14001521

14011522
///////////////////////////////////////////////////////////////////////////////
14021523
// struct AIRNET
14031524
// finds zone pressures that achieve balanced mass flows
14041525
///////////////////////////////////////////////////////////////////////////////
14051526
AIRNET::AIRNET()
1406-
: an_jac( NULL), an_V1( NULL), an_V2( NULL), an_mdotAbs( NULL), an_didLast( NULL),
1407-
an_nz(0)
1527+
: an_jac( NULL), an_V1( NULL), an_V2( NULL), an_mdotAbs( NULL), an_didLast( NULL),
1528+
an_nz(0)
14081529
{ an_resultsClear[0] = an_resultsClear[1] = 0;
14091530
} // AIRNET::AIRNET
14101531
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)