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
29 changes: 29 additions & 0 deletions doc/src/records/loadmeter.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,35 @@ Name of LOADMETER: required for assigning to ZONEs and RSYSs.
required: "Yes",
variability: "constant") %>

**lmtSubmeters=*list of up to 50 LOADMETERs***

A comma-separate list of LOADMETERs that are accumulated into this LOADMETER with optional multipliers (see lmtSubmeterMults). Submeters facilitate flexible categorization of loads results. In addition, use of lmtSubmeterMults allows load results from a representative model to be scaled and included in overall results. For example, a typical zone could be used to represent 5 similar spaces. The loads calculated for the typical zone could be assigned to a dedicated LOADMETER and that LOADMETER accumulated to a main LOADMETER with a multiplier of 5. Rules --

- A LOADMETER cannot reference itself as a submeter.
- A given LOADMETER can be referenced only once in the lmtSubmeters list.
- Circular references are not allowed.

<%= member_table(
units: "",
legal_range: "*names of LOADMETERs*",
default: "",
required: "No",
variability: "constant") %>

**lmtSubmeterMults=*list of up to 50 floats***

Submeter multipliers.

A note re default values: if lmtSubmeterMults is omitted, all multipliers are defaulted to 1. However, when lmtSubmeterMults is included, a multiplier value should be provided for each LOADMETER listed in lmtSubmeters since unspecified values are set to 0.

<%= member_table(
units: "",
legal_range: "",
default: "1",
required: "No",
variability: "constant") %>


**endLOADMETER**

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.
Expand Down
28 changes: 28 additions & 0 deletions doc/src/records/meter.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,34 @@ Cost of energy use per Btu.
required: "No",
variability: "constant") %>

**mtrSubmeters=*list of up to 50 METERs***

A comma-separate list of METERs that are accumulated into this METER with optional multipliers (see mtrSubmeterMults). Submeters facilitate flexible categorization of energy results. In addition, use of mtrSubmeterMults allows energy results from a representative model to be scaled and included in overall results. For example, a typical zone could be used to represent 5 similar spaces. The energy uses of the typical zone could be assigned to a dedicated METER that is accumulated to a main METER with a multiplier of 5. Rules --

- A METER cannot reference itself as a submeter.
- A given METER can be referenced only once in the mtrSubmeters list.
- Circular references are not allowed.

<%= member_table(
units: "",
legal_range: "*names of METERs*",
default: "",
required: "No",
variability: "constant") %>

**mtrSubmeterMults=*list of up to 50 floats***

Submeter multipliers.

A note re default values: if mtrSubmeterMults is omitted, all multipliers are defaulted to 1. However, when mtrSubmeterMults is included, a multiplier value should be provided for each METER listed in mtrSubmeters since unspecified values are set to 0.

<%= member_table(
units: "",
legal_range: "",
default: "1",
required: "No",
variability: "constant") %>

**endMeter**

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.
Expand Down
4 changes: 2 additions & 2 deletions doc/src/records/top-members.md
Original file line number Diff line number Diff line change
Expand Up @@ -957,9 +957,9 @@ CSE provides 3 mutually-exclusive methods for specifying cooling design conditio
- Design days (from weather file). One or more dates are specified. Actual days from the weather file are simulated.
- Monthly design data. Deprecated method using conditions found in ET1 format weather files.

**coolDsCond=*list of up to 13 DESCONDs***
**coolDsCond=*list of up to 12 DESCONDs***

Specifies cooling design conditions for cooling autosizing. A comma-separated list of up to 13 DESCOND names can be provided. Each day will be simulated repeatedly using weather conditions generated from DESCOND values.
Specifies cooling design conditions for cooling autosizing. A comma-separated list of up to 12 DESCOND names can be provided. Each day will be simulated repeatedly using weather conditions generated from DESCOND values.

<%= member_table(
units: "",
Expand Down
2 changes: 1 addition & 1 deletion src/CNDTYPES.DEF
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ PIPESEGP -- "class PIPESEG*"
}

// Energy end use
// CAUTION: MTR_IVL_SUB record (cnrecs.def) member ordering MATCHES order of choices.
// CAUTION: MTR_IVL record (cnrecs.def) member ordering MATCHES order of choices.
*choicb ENDUSECH {
CLG "Clg" // space cooling.
// CAUTION: code (cnguts,cgresult.cpp) assumes CLG is 1st.
Expand Down
73 changes: 54 additions & 19 deletions src/CNRECS.DEF
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ RECORD TOPRAT "top" *RAT /* top level RAT: contains control info and all once-on

//TOP: runtime time/day classification
*s IVLCH ivl // interval now starting or ending (C_IVLCH_Y, _M, etc),
// cnguts:doEndIvl/doBegIvl to doIvlExprs, doIvlAccum, mtrAccum, cgaccum, doIvlPrior, etc
// doEndIvl/doBegIvl to doIvlExprs, doIvlAccum, mtr_Accum1, cgaccum, doIvlPrior, etc
*s IVLCH isBegOf // 0 or interval now starting (for exprssion eval) (C_IVLCH_Y, _M, etc; 0 except during expr eval) ...
*s IVLCH isEndOf // ditto ending. ... set in cnguts.cpp, tested in cueval.cpp.
// autoSizing gets no end-month nor end-year unless caller sets isLastDay & does extra final rep 6-95.
Expand Down Expand Up @@ -2107,7 +2107,7 @@ RECORD FAN "fan sub" *SUBSTRUCT // FAN SUBRECORD
RECORD ZNISUB "zone sub" *SUBSTRUCT
*prefix zn_
// zone input info substruct, used in ZNR and ZNI
*declare "int IsCountable( int options) const { return options==0 || options==znModel; }"
*declare "bool IsCountable( int options) const { return options==0 || options==znModel; }"
*declare "float zn_HeightZ( float f) const;"
*declare "int zn_IsConvRad() const { return znModel >= C_ZNMODELCH_CZM; }"
*declare "int zn_IsUZ() const { return znModel >= C_ZNMODELCH_UZM; }"
Expand Down Expand Up @@ -2286,7 +2286,7 @@ RECORD ZNR "zone" *RAT // zone runtime info RAT. Set mainly from separate ZNI
*declare "BOO nxTu( TU *&tu);"
*declare "BOO nxZhx( ZHX *&x);"
*declare "BOO nxZhxSt( ZHX *&x);"
*declare "int IsCountable( int options) const { return i.IsCountable( options); }"
*declare "bool IsCountable( int options) const { return i.IsCountable( options); }"
*declare "int zn_IsConvRad() const { return i.zn_IsConvRad(); }"
*declare "int zn_IsUZ() const { return i.zn_IsUZ(); }"
*declare "int zn_IsSFModelSupported( int sfModel) const;"
Expand Down Expand Up @@ -3993,11 +3993,18 @@ RECORD LOADMTR_IVL "LOADMETER interval sub" *SUBSTRUCT // interval substruct fo
*END // LOADMTR_IVL
//=============================================================================
RECORD LOADMTR "LOADMETER" *RAT // LOADMETER: general way to track loads
*declare "RC lmt_CkF();"
*prefix lmt_
*declare "RC lmt_CkF( int options);"
*declare "RC lmt_BegSubhr();"
*declare "LOADMTR_IVL* lmt_GetLOADMTR_IVL( IVLCH ivl);"
*declare "void lmt_Accum( IVLCH ivl, int firstflg, int lastflg);"

*declare "bool lmt_HasSubmeter() const { return lmt_subMtri[ 0] != 0; }"
*declare "void lmt_AccumFromSubmeters();"

*r *array DIM_SUBMETERLIST TI lmt_subMtri; // submeters
*r *array DIM_SUBMETERLIST FLOAT lmt_subMtrMult // submeter multipliers

// accumulated values for each interval
// CAUTION: ordered for subscripting by IVLCH-1
*y *e *nest LOADMTR_IVL Y // run (aka year or annual)
Expand All @@ -4017,6 +4024,25 @@ RECORD DHWSYSRES_IVL "DHWSYSRES interval sub" *SUBSTRUCT // interval substruct
*declare "void wsr_AccumTick( const struct DHWTICK& tk, float tLpIn, float tCHDHWSupply=0.f);"
*declare "static const size_t wsr_NFLOAT;"

#if defined( DHWSYSRES_REV)
// energy (not fuel) exchanges with water, Btu
// values are for associated DHWSYS (wh_mult included, ws_mult not included)
// TODO: proposed sign convention -- everything wrt water except qLoad
*e FLOAT qLoad // hot water energy delivered to fixtures (> 0, opposite sign conv)
*e FLOAT qLoadHtg // space heating energy delivered, nz iff CHDHW (combined heat/DHW)
*e FLOAT qLoss // non-loop losses (jacket losses, T24DHW branch losses, )
*e FLOAT qLoop // DHWLOOP/DHWLOOPBRANCH losses
*e FLOAT qWHLoss // DHWHEATER tank loss (+ = to surround)
*e FLOAT qLHLoss // DHWLOOPHEATER tank loss (+ = to surround)
*e FLOAT qDWHR // drain water heat recovery
*e FLOAT qSSF // implied energy contribution from ws_SSF
*e FLOAT qSolar // DHWSOLARSYS contribution
*e FLOAT qWH // DHWHEATER primary (compressor, burner, )
*e FLOAT qLH // DHWLOOPHEATER primary
*e FLOAT qXBU // backup heating allocated to DHW
*e FLOAT qXBUHtg // backup heating allocated to space heating
// *e FLOAT qBal
#else
// water heating energy (not fuel), Btu
// values are for associated DHWSYS (wh_mult include, ws_mult not included)
*e FLOAT qLoad // hot water load (heat delivered to fixtures)
Expand All @@ -4029,6 +4055,7 @@ RECORD DHWSYSRES_IVL "DHWSYSRES interval sub" *SUBSTRUCT // interval substruct
*e FLOAT qWH // DHWHEATER primary (compressor, burner, )
*e FLOAT qLH // Loop heater primary
*e FLOAT qXBU // add'l backup heat
#endif

*END // DHWSYSRES_IVL
//=============================================================================
Expand Down Expand Up @@ -4625,9 +4652,9 @@ RECORD DHWHEATER "DHWHeater" *RAT // input / runtime DHW heater

*s *e FLOAT wh_qXBU; // current step HPWH add'l backup resistance heat, Btu
// output water heated to ws_tUse iff HPWH output temp < ws_tUse
*s *e DBL wh_qEnv; // current step heat removed by HPWH from environment, kWh
*s *e DBL wh_qEnv; // current step heat removed by HPWH from environment, Btu
// + = to water heater; for 1 DHWHEATER (no wh_mult)
*s *e DBL wh_qLoss; // current step HPWH standby losses, kWh. + = to surround
*s *e DBL wh_qLoss; // current step HPWH standby losses, Btu. + = to surround
// for 1 DHWHEATER (no wh_mult)
*s *e float wh_qHW; // current step hot water heating, Btu. always >= 0
// for 1 DHWHEATER (no wh_mult)
Expand Down Expand Up @@ -5394,12 +5421,13 @@ RECORD GAIN "gain" *RAT // (zone internal) Gain input and runtime
// note includes _TOTAL and _UNKNOWN
*END // GAIN
//=============================================================================
RECORD MTR_IVL_SUB "meter interval sub" *SUBSTRUCT // substruct for one meter for one interval for entire building
RECORD MTR_IVL "meter interval sub" *SUBSTRUCT // substruct for one meter for one interval for entire building
// use results

// accum functions; see CAUTION below
*declare "void mtr_Accum( ENDUSECH eu, float v) { if (eu) (&clg)[ eu-1] += v; }"
*declare "void mtr_Accum1( const MTR_IVL_SUB* mtrSub1, IVLCH ivl, int options=0);"
*declare "void mtr_AccumEU( ENDUSECH eu, float v) { if (eu) (&clg)[ eu-1] += v; }"
*declare "void mtr_Accum1( const MTR_IVL* mtrSub1, IVLCH ivl, int options=0);"
*declare "void mtr_AccumFromSubmeter( const MTR_IVL* subMtr, float mult);"
*declare "double mtr_NetBldgLoad() const;"
*declare "RC mtr_Validate( const MTR* mtr, IVLCH ivl) const;"

Expand Down Expand Up @@ -5439,26 +5467,33 @@ RECORD MTR_IVL_SUB "meter interval sub" *SUBSTRUCT // substruct for one meter f
*e float allEU // subtotal, clg .. usr2 (= load w/o bt and pv)
// cost results. for now (11-93), must report with probes. Code (cnguts) may assume in this order, after uses.
*p float cost // accumulated tot*rate
*p float dmdCost // largest dmd*dmdRate to month level, then accumulates (cnguts.cpp:mtrAccum)
//demand results. related code: cnguts.cpp:mtrAccum. for now, must be reported with probes. rob 11-93.
*p float dmdCost // largest dmd*dmdRate to month level, then accumulates (mtr_Accum)
//demand results. related code: mtr_Accum. for now, must be reported with probes.
*p float dmd // peak use in interval; hourly value same as .tot.
*p SHOY dmdShoy // peak time as subhour of year, subhr unused: 4*(hr+24*jDay).
*END // MTR_IVL_SUB
*END // MTR_IVL
//=============================================================================
RECORD MTR "meter" *RAT // Meter input/runtime: energy use by meter, interval, endUse for entire building 1-92
//inputs: rates
*i float rate // cost per Btu of use
*i float dmdRate // dmdCost per Btu of demand, for a month
*prefix mtr_

*declare "RC mtr_CkF( int options);"
*declare "void mtr_HrInit();"
*declare "bool mtr_HasSubmeter() const { return mtr_subMtri[ 0] != 0; }"
*declare "void mtr_AccumFromSubmeters();"

// inputs: rates
*i float rate // cost per Btu of use
*i float dmdRate // dmdCost per Btu of demand, for a month
*r *array DIM_SUBMETERLIST TI mtr_subMtri; // submeters
*r *array DIM_SUBMETERLIST FLOAT mtr_subMtrMult // submeter multipliers

//results: accumulated useage and cost for this meter (record subscript),
// for each interval (member here), usage by end use (substruct member):
//CAUTION: ordered for subscripting by IVLCH-1.
*y *e *nest MTR_IVL_SUB Y // run (aka year or annual) energy use
*m *e *nest MTR_IVL_SUB M // month's use
*d *e *nest MTR_IVL_SUB D // day's use
*h *e *nest MTR_IVL_SUB H // hour's use
*y *e *nest MTR_IVL Y // run (aka year or annual) energy use
*m *e *nest MTR_IVL M // month's use
*d *e *nest MTR_IVL D // day's use
*h *e *nest MTR_IVL H // hour's use
*END // MTR
//=============================================================================
RECORD HDAY "holiday" *RAT // describes one holiday for HdayiB/HdayB RAT. several default records are supplied.
Expand Down
38 changes: 38 additions & 0 deletions src/ancrec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,44 @@ basAnc::basAnc( int flags, SFIR * _fir, USI _nFlds, char * _what, USI _eSz, RCT
if (ba_flags & RFTYS)
dmfree( DMPP( what));
} // basAnc::~basAnc
//-----------------------------------------------------------------------------
int basAnc::GetCount() const // return # of records
{
int count = 0;
for (int i = mn; i <= n; i++)
if (rec(i).gud)
++count;
return count;

} // basAnc::GetCount
//-----------------------------------------------------------------------------
int basAnc::MakeRecordList(
char* list,
size_t listDim,
const char* brk,
const char* (*proc)(const record* pR) /*=nullptr*/) const

{
int count = 0;
*list = '\0';
for (int i = mn; i <= n; i++)
{
const record* pR = &rec(i);
if (pR->gud)
{
const char* s1 = proc != nullptr
? (*proc)(pR) : pR->name;
if (s1 != nullptr)
{
strCatIf(list, listDim, brk, s1);
++count;
}
}
}

return count;

} // MakeRecordList
//---------------------------------------------------------------------------------------------------------------------------
void FC basAnc::regis() // "register" anchor for nextAnc() iteration. Constructor helper.
{
Expand Down
49 changes: 32 additions & 17 deletions src/ancrec.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class basAnc // base class for record anchors: basAnc<recordName>
virtual void** pptr() = 0;
virtual void setPtr( record* r) = 0;
virtual record& rec(TI i) = 0; // { return (record)((char *)ptr() + i*eSz); } // access record i
virtual const record& rec(TI i) const = 0; // ditto const
virtual record* GetAtSafe( int i) const = 0; // typed pointer to ith record or NULL
virtual void* recMbr(TI i, USI off) = 0; // point record i member by offset
void * FC recFld(TI i, SI fn); // point record i member by FIELD # 3-92
Expand All @@ -114,6 +115,8 @@ class basAnc // base class for record anchors: basAnc<recordName>
const char* getChoiTx( int fn, int options=0, SI chan=-1, BOOL* bIsHid=NULL) const;
void an_SetCULTLink( const CULT* pCULT) { an_pCULT = pCULT; }
static void an_SetCULTLinks();
int GetCount() const;
int MakeRecordList(char* list, size_t listDim, const char* brk, const char* (*proc)(const record* pR)=nullptr) const;

protected:
virtual void conRec( TI i, SI noZ=0) = 0; // execute constructor for record i
Expand Down Expand Up @@ -222,7 +225,7 @@ class record // base class for records
record& Copy( const record& d) { Copy( &d); return *this; }
record& operator=( const record& d) { Copy( &d); return *this; }
virtual void Copy( const record* pSrc, int options=0);
virtual int IsCountable([[maybe_unused]] int options ) const { return 1; }
virtual bool IsCountable(int /*options*/) const { return true; }
virtual void FixUp() { }; // optional fixup after reAl()
void SetName( const char* _name) { strncpy0( name, _name, sizeof( ANAME)); }
int IsNameMatch( const char* _name) const;
Expand Down Expand Up @@ -312,18 +315,37 @@ template <class T> class anc : public basAnc

T* p; // typed pointer to record array storage block
virtual T* GetAtSafe( int i) const // typed pointer to ith record or NULL
{ return i<mn || i>n ? NULL : p+i; }
{ return i<mn || i>n ? NULL : p+i; }
T* GetAt(int i) const // typed pointer to ith record
{
#if defined( _DEBUG)
if (i < mn || i > n)
warn("%s GetAt(): %d out of range", what, i);
#endif
return p + i;
}
T& operator[]( int i) const { return *GetAt( i); } // typed ref to ith record
bool GetAtGud(int i, T* &r) const
{
if (i >= mn && i <= n && (p + i)->gud)
{ r = p + i;
return true;
}
else
{
#if defined( _DEBUG)
T* GetAt( int i) const; // typed pointer to ith record (checks i)
#else
T* GetAt( int i) const { return p+i; } // typed pointer to ith record (inline)
warn("%s GetAtGud(): %d out of range or not gud", what, i);
#endif
T& operator[]( int i) { return *GetAt( i); } // typed ref to ith record
r = nullptr;
return false;
}
} // GetAtGud

virtual record* ptr() { return p; } // access block ptr (in base class / generic code)
virtual void** pptr() { return (void **)&p; }
virtual void setPtr( record* r) { p = (T*)r; }
virtual record& rec(TI i) { return p[i]; } // access record i in base/generic code
virtual const record& rec(TI i) const { return p[i]; }
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, const char* name=NULL)
{ return basAnc::add((record **)r, erOp, i, name); }
Expand All @@ -332,6 +354,7 @@ template <class T> class anc : public basAnc
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;


protected:
void desRecs( TI mn=0, TI n=32767); // ~ all records or range (as b4 freeing block)
virtual void desRec( TI i)
Expand Down Expand Up @@ -425,12 +448,13 @@ template <class T> void anc<T>::desRecs( SI _mn, SI _n)
desRec(i); // conditionally destroy record in space with record-deriv d'tor ~T.
} // anc<T>::desRecs
//-------------------------------------------------------------------------------------------------
template <class T> int anc<T>::GetCount( int options /*=0*/) const
template <class T> int anc<T>::GetCount(
int options) const // passed to T.IsCountable
{
int count = 0;
const T* pT;
RLUP( *this, pT)
{ if (!options || pT->IsCountable( options))
{ if (pT->IsCountable( options))
count++;
}
return count;
Expand Down Expand Up @@ -490,15 +514,6 @@ template <class T> RC anc<T>::AllocResultsRecs( // allocate/init results record

return rc;
} // anc< T>::AllocResultsRecs
//-----------------------------------------------------------------------------
#if defined( _DEBUG)
template <class T> T* anc<T>::GetAt( int i) const
{
if (i < mn || i > n)
warn( "%s GetAt(): %d out of range", what, i);
return p+i;
} // anc<T>::GetAt
#endif
//=============================================================================

///////////////////////////////////////////////////////////////////////////////
Expand Down
Loading