Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/ANCREC.CPP
Original file line number Diff line number Diff line change
Expand Up @@ -592,14 +592,18 @@ RC FC basAnc::free() // free (non-static) record memory block for anchor
return RCOK;
} // basAnc::free
//---------------------------------------------------------------------------------------------------------------------------
RC basAnc::add( record **_r, int erOp, TI i/*=0*/) // construct record i (0 = next). Allocs if nec.
RC basAnc::add( // construct record i (0 = next). Allocs if nec.
record **_r, // returned: ptr to add record
int erOp, // error handling
TI i/*=0*/, // where to add
const char* _name /*=NULL*/) // optional name for added record
{
#ifdef DEBUG2
if (validate("basAnc::add", erOp)) return RCBAD; // check anchor
if (validate("basAnc::add", erOp)) // check anchor
return RCBAD;
#endif
if (!i) // if we are to choose record number
{
i = mn; // 1: record # 0 is not used
{ i = mn; // 1: record # 0 is not used
if (ptr())
{
while (i <= n && rec(i).gud) i++; // find record space with gud==0 else 1 more than last used.
Expand All @@ -611,15 +615,14 @@ RC basAnc::add( record **_r, int erOp, TI i/*=0*/) // construct record i (0 = ne
|| !ptr() ) // insurance
{
ULI sz = (ULI)nAl*eSz + 1024; // new size in bytes to add 1 + 1K's worth of record spaces (nAl is +1)
#if 0 // eliminate 64K limit, 9-10
x setToMin( sz, 0x0000FFF0UL); // don't go over 64K to get the 1K+1. Allow a few overhead bytes.
#endif
register TI _n = max( (USI)(sz/eSz), (USI)i); // add 1 + 1K's worth of spaces, or to req'd rec # if more.
if (reAl(_n, erOp))
return RCBAD; // (re)alloc rec spaces 1.._n, init nAl, ptr(), space[0], etc. above.
}
conRec(i); // construct record i: mark in use, zero, init std base members, do specific record init.
*_r = &rec(i); // return pointer to the added record
if (_name)
(*_r)->SetName(_name);
if (i > n)
n = i; // increase max in-use subscript (loop limit) to that just allocated
return RCOK; // error returns above
Expand All @@ -638,7 +641,7 @@ RC FC basAnc::del( TI i, int erOp/*=ABT*/) // delete (squeeze out) ith record
{
if (!dest.gud)
conRec(i); // construct destination if nec to insure vftp, rt, b, ss set.
dest.CopyFrom(&src); // copy record i+1 to i without dup'ing heap ptrs
dest.CopyFrom(&src); // copy record i+1 to i without dup'ing heap ptrs
// tentatively no destroy: does nothing in base class, and deriv class might delete heap ptrs we did not dup.
#if defined( _DEBUG)
dest.Validate();
Expand Down
12 changes: 7 additions & 5 deletions src/ANCREC.H
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ class basAnc // base class for record anchors: basAnc<recordName>
BP ownB; // 0 or ptr to anchor whose objects own this anchor's objects (record.ownTi)
const CULT* an_pCULT; // NULL or associated CULT input table for records of this type
// simplifies back translation of input names

basAnc();
basAnc( int flags, SFIR * fir, USI nFlds, char * what, USI eSz, RCT rt, USI sOff, int dontRegister=0 );
void FC regis();
Expand All @@ -101,7 +100,7 @@ class basAnc // base class for record anchors: basAnc<recordName>
RC FC al( TI n, int erOp=ABT, BP _ownB=NULL); // allocate records block. destroys old recs.
RC FC reAl( TI n, int erOp=ABT); // (re)allocate records block. keeps old recs <= n.
RC FC free(); // free block
RC add( record **r, int erOp, TI i=0); // add record to block
RC add( record **r, int erOp, TI i=0, const char* _name=NULL); // add record to block
RC FC del( TI i, int erOp=ABT); // delete record i
void statSetup( record &r, TI n=1, SI noZ=0, SI inHeap=0); // set up with static record(s)
int isNamed() const { return ba_flags & RFNAMED; } // records have .name[]: always on, coding out 7-92
Expand Down Expand Up @@ -308,8 +307,9 @@ template <class T> class anc : public basAnc
virtual void setPtr( record* r) { p = (T*)r; }
virtual record& rec(TI i) { return p[i]; } // access record i in base/generic code
virtual void * recMbr(TI i, USI off) { return (void *)((char *)(p + i) + off); } // point record i member by offset
RC add( T **r, int erOp, TI i = 0) { return basAnc::add((record * *)r, erOp, i); }
RC RunDup( const anc< T> &src, BP _ownB=NULL, int erOp=ABT);
RC add( T **r, int erOp, TI i = 0, const char* name=NULL)
{ return basAnc::add((record **)r, erOp, i, name); }
RC RunDup( const anc< T> &src, BP _ownB=NULL, int nxRecs=0, int erOp=ABT);
RC AllocResultsRecs(basAnc& src);
void statSetup( T &r, TI n=1, SI noZ=0, SI inHeap=0) { basAnc::statSetup( r, n, noZ, inHeap); }
int GetCount( int options=0) const;
Expand Down Expand Up @@ -421,6 +421,8 @@ template <class T> int anc<T>::GetCount( int options /*=0*/) const
template <class T> RC anc<T>::RunDup( // duplicate records for run
const anc<T> &src, // source array (e.g. input data)
BP _ownB /*= NULL*/, // owner (if any)
int nxRecs /*=0*/, // # of extra run records to allocate
// (e.g. for "sum-of-all")
int erOp /*=ABT*/) // error action re alloc fail
// typically ABT, no remedy
// typical use = input -> run
Expand All @@ -429,7 +431,7 @@ template <class T> RC anc<T>::RunDup( // duplicate records for run
// allows record-level run cancel
{
// delete old records, alloc to needed size for min fragmentation
RC rc = al(src.n, erOp, _ownB);
RC rc = al(src.n+nxRecs, erOp, _ownB);

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

Expand Down
155 changes: 138 additions & 17 deletions src/CGCOMP.CPP
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,76 @@ float TOPRAT::tp_WindPresV( // wind velocity pressure
} // TOPRAT::tp_WindPresV
//===============================================================================

///////////////////////////////////////////////////////////////////////////////
// AFMTR_IVL, AFMTR: accumulates air mass flow by category
///////////////////////////////////////////////////////////////////////////////
/*static*/ const int AFMTR_IVL::NAFCATS
= (sizeof(AFMTR_IVL) - offsetof( AFMTR_IVL, amt_total)) / sizeof(float);
// NAFCATS s/b same as AFCAT choices + 1 (for total)
static_assert(AFMTR_IVL::NAFCATS == C_AFCAT_COUNT+1, "Inconsistent AFMTR constants");
//-----------------------------------------------------------------------------
void AFMTR_IVL::amt_Copy(
const AFMTR_IVL* s)
{
memcpy(this, s, sizeof(AFMTR_IVL));
} // AFMTR_IVL::amt_Copy
//-----------------------------------------------------------------------------
void AFMTR_IVL::amt_Accum( // accumulate
const AFMTR_IVL* sIvl, // source
int firstFlg, // true iff first accum into this (beg of ivl)
int lastFlg) // true iff last accum into this (end of ivl)

{
if (firstFlg)
{ amt_Copy(sIvl);
amt_count = 1;
}
else
{ VAccum(&amt_total, NAFCATS, &sIvl->amt_total);
amt_count++;
}
if (lastFlg)
VMul1(&amt_total, NAFCATS, 1.f / amt_count);
} // AFMTR_IVL
//-----------------------------------------------------------------------------
RC AFMTR::amt_CkF()
{
return RCOK;
}
//-----------------------------------------------------------------------------
RC AFMTR::amt_BegSubhr() // init at beg of subhr
{
S.amt_Clear();
return RCOK;
} // AFMTR::amt_BegSubhr
//-----------------------------------------------------------------------------
void AFMTR::amt_AccumCat( // accumulate air flow value for current subhour
AFCAT afCat, // air flow category
float amf) // air mass flow, lbm/sec
{
if (amf > 0.f) // record only flow into zone
{ // convert lbm/s -> cfm std air
S.amt_AccumCat(afCat, AMFtoAVF2( amf));
}
} // AFMTR::amt_AccumCat
//-----------------------------------------------------------------------------
void AFMTR::amt_Accum(
IVLCH ivl, // destination interval: hour/day/month/year
// Accumulates from subhour/day/month. Not Top.ivl!
int firstFlg, // iff TRUE, destination will be initialized before values are accumulated into it
int lastFlg) // iff TRUE, destination averages will be computed as needed
{
AFMTR_IVL* dIvl = &Y + (ivl - C_IVLCH_Y); // point destination substruct for interval
// ASSUMES interval members ordered like DTIVLCH choices
AFMTR_IVL* sIvl = dIvl + 1; // source: next shorter interval

// accumulate: copy on first call (in lieu of 0'ing dIvl).
// Note: amt_Init() call in doBegIvl 0s H values
dIvl->amt_Accum(sIvl, firstFlg, lastFlg);
} // AFMTR::amt_Accum
//=============================================================================


/////////////////////////////////////////////////////////////////////////////////
// AIRSTATE
/////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -704,8 +774,7 @@ RC IZXRAT::iz_SetupHERV() // set mbrs re HERV model
DbPrintf( "HERV '%s' in: avf=%.2f rho=%.5f mdotP=%.5f\n out: avf=%.2f rho=%.5f mdotP=%.5f\n",
name, avfGross, iz_rho2, ad.ad_mdotP, avfGross*iz_vfExhRat, rhoX, ad.ad_mdotX);
#endif



// iz_air2 / iz_rho2 = air state into z1
// Note: calc HX with moist air mass flow rates
// some sources say dry AMF, not fully understood
Expand Down Expand Up @@ -951,9 +1020,54 @@ x }

iz_SetupNonAirNet(); // calc izxfer derived values

iz_SetupAfMtrs(); // AFMETER (air flow meter) setup

return rc;
} // IZXRAT::iz_Setup()
} // IZXRAT::iz_Setup
#undef ZFAN
//-------------------------------------------------------------------
void IZXRAT::iz_SetupAfMtrs()
{
// Air flow category
if (iz_afCat == 0)
iz_afCat = iz_AfCatDefault();

// AFMTR ptrs: NULL if no meter specified -> no air flow accounting
// one pointer for positive flows, one for negative
const ZNR* zp;
if (iz_zi1 > 0)
{ zp = ZrB.GetAt(iz_zi1);
iz_pPosAfMtr = AfMtrR.GetAtSafe(zp->i.zn_afMtri);
}
if (iz_zi2 > 0)
{ zp = ZrB.GetAt(iz_zi2);
iz_pNegAfMtr = AfMtrR.GetAtSafe(zp->i.zn_afMtri);
}
} // IZXRAT::iz_SetupAfMtrs
//-----------------------------------------------------------------------------
AFCAT IZXRAT::iz_AfCatDefault() const
{
AFCAT afCat;
if (iz_IsSysAir())
afCat = C_AFCAT_HVAC;
else if (iz_IsDuctLk())
afCat = C_AFCAT_DUCTLK;
else if (iz_IsExterior())
{ if (iz_IsFixedFlow())
afCat = C_AFCAT_FANEX;
else
afCat = C_AFCAT_INFILEX;
}
else
{ if (iz_IsFixedFlow())
afCat = C_AFCAT_FANIZ;
else
afCat = C_AFCAT_INFILIZ;
}

return afCat;

} // IZXRAT::iz_AfcatDefault
//-----------------------------------------------------------------------------
RC IZXRAT::iz_SetupNonAirNet() // interzone transfer one-time initialization

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

ize->iz_SetupAfMtrs(); // default iz_afCat, set up AFMTR linkage

// more init?

return ize->ss;
Expand Down Expand Up @@ -1255,7 +1371,6 @@ RC IZXRAT::iz_Calc()
ZNR* zp1 = ZrB.GetAt( iz_zi1);
ZNR* zp2 = ZrB.GetAt( iz_zi2);
float tdif = zp1->tzls - zp2->tzls; // temp diff between zones
#if 1
if (iz_nvcntrl != C_IZNVTYCH_ONEWAY || tdif > 0.f)
{ double hx = iz_ua;
if (iz_nvcntrl != C_IZNVTYCH_NONE)
Expand All @@ -1264,15 +1379,6 @@ RC IZXRAT::iz_Calc()
zp1->zn_qIzXAnSh -= qx; // accumulate heat/hour to zone
zp2->zn_qIzXAnSh += qx; // same for other zone, opposite sign: positive into zone.
}
#else
x float hx = iz_ua; // coupling coeff: init to constant (conduction) portion
x if (iz_nvcntrl==C_IZNVTYCH_TWOWAY) // if nat vent tween zones
x hx += iz_nvcoeff * sqrt( fabs( tdif)); // it is proportional to sqrt temp difference
x float qx = hx * tdif; // heat xfer per hour (power): coupling * temp diff.
x // positive for xfer from zn1 to zn2
x zp1->zn_qIzXAnSh -= qx; // accumulate heat/hour to zone
x zp2->zn_qIzXAnSh += qx; // same for other zone, opposite sign: positive into zone.
#endif
return RCOK;
} // IZXRAT::iz_Calc
//--------------------------------------------------------------------------------
Expand Down Expand Up @@ -1380,7 +1486,6 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
{
ZNR* zp = ZrB.GetAt( iz_zi1); // zone
float fVent = zp->zn_fVent;
iz_amfNom = (1.f-fVent)*iz_ad[ 0].ad_mdotP + fVent*iz_ad[ 1].ad_mdotP;
if (iz_HasFan() && iz_fan.fn_mtri)
{ // calc fan electricity and accum to meter
// need venting fraction to determine fan operation
Expand All @@ -1393,18 +1498,34 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
iz_fan.fn_endUse, // user-specified end use (default = "fan")
fanPwr * Top.subhrDur); // electrical energy, Btu (*not* Wh)
}

// air flow accounting
iz_amfNom // nominal flow, lbm/sec
= (1.f - fVent)*iz_ad[0].ad_mdotP + fVent * iz_ad[1].ad_mdotP;
if (iz_nvcntrl == C_IZNVTYCH_ANHORIZ)
iz_amfNom
+= (1.f - fVent)*iz_ad[0].ad_mdotB + fVent * iz_ad[1].ad_mdotB;
if (iz_amfNom > 0.f)
{ if (iz_pPosAfMtr)
iz_pPosAfMtr->amt_AccumCat(iz_afCat, iz_amfNom);
}
else if (iz_amfNom < 0.f)
{ // flow is out of zn1 = into zn2
if (iz_pNegAfMtr)
iz_pNegAfMtr->amt_AccumCat(iz_afCat, -iz_amfNom);
}

return RCOK;
} // IZXRAT::iz_EndSubhr

//=============================================================================

///////////////////////////////////////////////////////////////////////////////
// struct AIRNET
// finds zone pressures that achieve balanced mass flows
///////////////////////////////////////////////////////////////////////////////
AIRNET::AIRNET()
: an_jac( NULL), an_V1( NULL), an_V2( NULL), an_mdotAbs( NULL), an_didLast( NULL),
an_nz(0)
: an_jac( NULL), an_V1( NULL), an_V2( NULL), an_mdotAbs( NULL), an_didLast( NULL),
an_nz(0)
{ an_resultsClear[0] = an_resultsClear[1] = 0;
} // AIRNET::AIRNET
//-----------------------------------------------------------------------------
Expand Down
Loading