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
7 changes: 5 additions & 2 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
config: Release
arch: "64"
compiler: clang
experimental: false
experimental: true
# - os: ubuntu
# os_ver: "22.04"
# config: Release
Expand Down Expand Up @@ -78,7 +78,7 @@ jobs:
id: test
run: ctest -C ${{ matrix.config }} -j ${{ steps.cpu-cores.outputs.count }} --output-on-failure -E shadetest # CI can't do GPU calcs at this time (the steps above get us close, but throws an exception on destruction)
working-directory: build
continue-on-error: false
continue-on-error: true
- name: Upload report files artifact
if: steps.test.outcome == 'failure'
uses: actions/upload-artifact@v4
Expand All @@ -87,6 +87,9 @@ jobs:
path: |
test/*.rep
test/*.REP
- name: Check test failure
if: steps.test.outcome == 'failure'
run: exit 1
build-doc:
strategy:
fail-fast: false
Expand Down
2 changes: 1 addition & 1 deletion cmake/build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if (NOT DEFINED TARGET_NAME)
set(TARGET_NAME "all")
endif ()
endif ()
message("Building ${TARGET_NAME}...")
message(STATUS "Building ${TARGET_NAME}...")

include(cmake/utility.cmake)
set_build_configuration()
Expand Down
18 changes: 2 additions & 16 deletions doc/src/records/battery.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ Name of the battery system. Given after the word BATTERY.

**btMeter=*choice***

Name of a meter by which the BATTERY's power input/output (i.e., charge/discharge) is recorded. Charges to the BATTERY system would be seen as a positive powerflow while discharges from the BATTERY system would be seen as a negative value.
Name of a METER to which the BATTERY's charge/discharge energy flows are recorded. Battery energy flows are accumulated to meter end use "BT". Battery energy flows are seen from the standpoint of a "load" on the electric grid, so charges to the BATTERY system are positive values while discharges from the BATTERY system are negative values.

Note btMeter determines the source for the probe value *loadSeen*. See discussion and example under btChgReq (below).
Note btMeter also determines the source for the probe value *loadSeen*. See discussion and example under btChgReq (below).

<%= member_table(
units: "",
Expand All @@ -30,20 +30,6 @@ Note btMeter determines the source for the probe value *loadSeen*. See discussi
variability: "constant")
%>

**btEndUse=*choice***

Meter end use to which the BATTERY's charged/discharged energy should be accumulated. Note that the battery end use is seen from the standpoint of a "load" on the electric grid. That is, when the battery is being charged, the end use will show up as positive. When the battery is being discharged (i.e., when it is offsetting other loads), it is seen as negative.

<%= insert_file('doc/src/enduses.md') %>

<%= member_table(
units: "",
legal_range: "*Codes listed above*",
default: "BT",
required: "No",
variability: "constant")
%>

**btChgEff=*float***

The charging efficiency of storing electricity into the BATTERY system. A value of 1.0 means that no energy is lost and 100% of charge energy enters and is stored in the battery.
Expand Down
4 changes: 2 additions & 2 deletions src/CNRECS.DEF
Original file line number Diff line number Diff line change
Expand Up @@ -5434,7 +5434,6 @@ RECORD BATTERY "Battery" *RAT // input / runtime battery
*declare "float bt_ChgReqTDVPeakSave();"

*i TI bt_meter; // meter for system electricity production
*f ENDUSECH bt_endUse // end use of energy. defaults to "BT"
*r NOYESCH bt_useUsrChg // YES: user specifies charge request;
// NO (default): calculate charge request via
// default strategy
Expand Down Expand Up @@ -5587,7 +5586,8 @@ RECORD MTR "meter" *RAT // Meter input/runtime: energy use by meter, interval,
*declare "RC mtr_CkF( int options);"
*declare "void mtr_HrInit();"
*declare "bool mtr_HasSubmeter() const { return mtr_subMtri[ 0] != 0; }"
*declare "void mtr_AccumFromSubmeters();"
*declare "enum ACCUMOPT { ALL, BATTERYONLY};"
*declare "void mtr_AccumFromSubmeters( ACCUMOPT opt);"
*declare "RC mtr_Validate() const;"
*declare "MTR_IVL* mtr_GetMTRIVL( int ivl) { return &Y + (ivl - C_IVLCH_Y); }"
*declare "const MTR_IVL* mtr_GetMTRIVL( int ivl) const { return &Y + (ivl - C_IVLCH_Y); }"
Expand Down
32 changes: 16 additions & 16 deletions src/ancrec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ record::record(BP _b, TI i, SI noZ/*=0*/) // construct record i of basAnc b, z
b = _b;
rt = _b->rt;
ss = i; // set base class members, for appl and anchor class use
gud = 1; // say space in use and record good
r_status = 1; // say space in use and record good
} // record::record
//---------------------------------------------------------------------------------------------------------------------------
void* record::field( int fn) // point to member in record by FIELD #
Expand Down Expand Up @@ -124,7 +124,7 @@ int record::IsNameMatch( const char* _name) const
return !_stricmp( _name, Name());
} // record::IsNameMatch
//-----------------------------------------------------------------------------
/*virtual*/ void record::Copy( // copy user and ul data and 'gud' from another record of same type
/*virtual*/ void record::Copy( // copy user and ul data and r_status from another record of same type
const record* pSrc, // source record
int options/*=0*/) // rcoLEAVENAME: do NOT copy name
{
Expand All @@ -137,7 +137,7 @@ int record::IsNameMatch( const char* _name) const
#endif

// bitwise copy members preceding name (not including internal members)
int offBeg = offsetof(record, gud);
int offBeg = offsetof(record, r_status);
int offEnd = offsetof(record, name);
memcpy((char*)this + offBeg, (const char*)pSrc + offBeg, offEnd - offBeg);

Expand Down Expand Up @@ -804,8 +804,7 @@ int basAnc::GetCount() const // return # of records
{
int count = 0;
for (int i = mn; i <= n; i++)
if (rec(i).gud)
++count;
count += rec(i).r_status > 0;
return count;

} // basAnc::GetCount
Expand All @@ -822,7 +821,7 @@ int basAnc::MakeRecordList(
for (int i = mn; i <= n; i++)
{
const record* pR = &rec(i);
if (pR->gud)
if (pR->r_status > 0)
{
const char* s1 = proc != nullptr
? (*proc)(pR) : pR->Name();
Expand Down Expand Up @@ -856,7 +855,7 @@ void FC basAnc::regis() // "register" anchor for nextAnc() iteration. Constr
//---------------------------------------------------------------------------------------------------------------------------
void basAnc::desRecs( SI _mn, SI _n)
{
//if (mn <= n) // if any records allocated: protection for ptr vf call if nec??
//if (mn <= n) // if any records allocated: protection for ptr vf call if nec??
if (ptr()) // if record memory is allocated
for (TI i = max(mn,_mn); i <= min(n,_n); i++) // loop allocated record spaces in range given by caller
desRec(i); // conditionally destroy record in space
Expand Down Expand Up @@ -944,7 +943,7 @@ RC FC basAnc::reAl( TI _n, int erOp/*=ABT*/) // allocate space for n (0=default

// loop all pre-reAl gud records
for (int i=mn; i<=n ; i++)
if (rec( i).gud)
if (rec( i).r_status > 0)
rec( i).FixUp(); // virtual, allow record to fix e.g. link ptrs
}
return rc;
Expand Down Expand Up @@ -975,10 +974,10 @@ RC basAnc::add( // construct record i (0 = next). Allocs if nec.
{ 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.
while (i <= n && rec(i).r_status) i++; // find record space with gud==0 else 1 more than last used.
}
}
else if (i <= n && rec(i).gud) // else if have (unexpected) request to "add" existing in-use record
else if (i <= n && rec(i).r_status) // else if have (unexpected) request to "add" existing in-use record
desRec(i); // destroy that record's current contents (eg free deriv class heap ptrs)
if ( i >= nAl // if (more) record spaces must be allocated (nAl is +1; i,n are not)
|| !ptr() ) // insurance
Expand Down Expand Up @@ -1006,9 +1005,9 @@ RC FC basAnc::del( TI i, int erOp/*=ABT*/) // delete (squeeze out) ith record
{
record& dest = rec(i);
record& src = rec(i+1);
if (src.gud) // if next record good
if (src.r_status) // if next record good
{
if (!dest.gud)
if (!dest.r_status)
conRec(i); // construct destination if nec to insure vftp, rt, b, ss set.
dest.Copy( &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.
Expand All @@ -1017,12 +1016,13 @@ RC FC basAnc::del( TI i, int erOp/*=ABT*/) // delete (squeeze out) ith record
#endif
}
else // (not currently expected 2-92)
dest.gud = 0; // nothing to copy from next slot, say this slot is free
dest.r_status = 0; // nothing to copy from next slot, say this slot is free
}
rec(i).gud = 0; // say vacated slot at end is free
// if possible leftover undup'd ptrs in vacated slots with gud=0 are a problem, CONSTRUCT the slots (conRec(i)) to zero data.
rec(i).r_status = 0; // say vacated slot at end is free
// if possible leftover undup'd ptrs in vacated slots with r_status=0 are a problem,
// CONSTRUCT the slots (conRec(i)) to zero data.
n--; // max subscript is one less
return RCOK; // error return above.
return RCOK; // error return above.
} // basAnc::del
//---------------------------------------------------------------------------------------------------------------------------
void basAnc::statSetup( // init anchor with given non-expandable static record memory
Expand Down
24 changes: 14 additions & 10 deletions src/ancrec.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class basAnc // base class for record anchors: basAnc<recordName>
RCT rt; // record type (from rcdef.exe); now mainly for internal checks
// members set by basAnc mbr fcns
TI nAl; // max+1 allocated space subscript (non-static)
TI mn, n; // minimum (0 or 1) and max NOT+1 used record subscript (spaces unused if .gud==0)
TI mn, n; // minimum (0 or 1) and max NOT+1 used record subscript (spaces unused if .r_status==0)
inline int GetSSRange() const { return n-mn+1; } // count INCLUDING UNUSED
inline int GetSS0() const { return mn; } // subscript of 0th entry
int ba_flags; // bits, RFxxxx defines above -- also set by user
Expand Down Expand Up @@ -116,6 +116,10 @@ class basAnc // base class for record anchors: basAnc<recordName>
void an_SetCULTLink( const CULT* pCULT) { an_pCULT = pCULT; }
static void an_SetCULTLinks();
int GetCount() const;
int GetCountMax() const
{ return n-mn+1; // max possible # records (includes unused)
// faster than GetCount()
}
int MakeRecordList(char* list, size_t listDim, const char* brk, const char* (*proc)(const record* pR)=nullptr) const;

protected:
Expand All @@ -142,7 +146,7 @@ class record // base class for records
RCT rt; // record type (from rcdef.exe); now mainly for internal checks
TI ss; // record subscript
BP b; // pointer to record's anchor; 0 may indicate unconstructed record space.
SI gud; // 0: free; > 0: good record; [<0, skip/retain]. bits 0x7ffe avail to appl.
SI r_status; // 0: free; > 0: good record; [<0, skip/retain]. bits 0x7ffe avail to appl.
// overhead members for appl user language (ul). CAUTION check record::Copy if these members changed.
TI ty, li; // 0 or user language TYPE and LIKE subscripts
int fileIx; // 0 or source file name index: see ancrecs:getFileName and getFileIx. 2-94.
Expand All @@ -157,7 +161,7 @@ class record // base class for records
// base class functions
record( BP _b, TI i, SI noZ=0); // construct, as record i for anchor b, 0 mbrs unless noZ
// override for records with specific destructor requirements such as heap pointers to delete:
virtual ~record() { gud = 0; } // base destructor: say record space is free
virtual ~record() { r_status = 0; } // base destructor: say record space is free
virtual void DelSubOjects( int /*options*/=0) {} // override to delete records heap objects
virtual RC RunDup(const record* pSrc, int options=0) { Copy(pSrc, options); return RCOK; }
virtual void ReceiveRuntimeMessage( const char* /*msg*/) { }
Expand Down Expand Up @@ -340,7 +344,7 @@ template <class T> class anc : public basAnc
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)
if (i >= mn && i <= n && (p + i)->r_status)
{ r = p + i;
return true;
}
Expand Down Expand Up @@ -371,7 +375,7 @@ template <class T> class anc : public basAnc
protected:
void desRecs( TI mn=0, TI n=32767); // ~ all records or range (as b4 freeing block)
virtual void desRec( TI i)
{ if (p[i].gud)
{ if (p[i].r_status)
p[i].T::~T(); // destroy record if constructed
}

Expand All @@ -383,29 +387,29 @@ template <class T> class anc : public basAnc
}; // class anc<T>
//=============================================================================
//----- macro to loop over records of given anchor (type known) (hook to change re skipping deleted records)
#define RLUP( B, rp) for (rp=(B).p+(B).mn; rp <= (B).p + (B).n; rp++) if (rp->gud > 0)
#define RLUP( B, rp) for (rp=(B).p+(B).mn; rp <= (B).p + (B).n; rp++) if (rp->r_status > 0)

//----- macro to loop over records of given anchor (type known) in reverse (hook to change re skipping deleted records)
#define RLUPR( B, rp) for (rp=(B).p+(B).n; rp >= (B).p+(B).mn; rp--) if (rp->gud > 0)
#define RLUPR( B, rp) for (rp=(B).p+(B).n; rp >= (B).p+(B).mn; rp--) if (rp->r_status > 0)

//----- macro to loop over records of given anchor (type known) (hook to change re skipping deleted records)
//----- variant with condition
#define RLUPC( B, rp, C) for (rp=(B).p+(B).mn; rp <= (B).p + (B).n; rp++) if (rp->gud > 0 && (C))
#define RLUPC( B, rp, C) for (rp=(B).p+(B).mn; rp <= (B).p + (B).n; rp++) if (rp->r_status > 0 && (C))

#if 0
0 unused
0 //----- macro to loop over records of generic anchor (record type not known) (hook to change re skipping deleted records)
0 #define RLUPGEN( B, rp) for ( rp = (record *)( (char *)(B).ptr() + (B).eSz*(B).mn ); \
0 rp <= (record *)( (char *)(B).ptr() + (B).eSz*(B).n ); \
0 (char *)rp += (B).eSz ) \
0 if (((record *)rp)->gud > 0)
0 if (((record *)rp)->r_status > 0)
#endif

//----- macro to loop over records of generic anchor in member fcn (hook to change re skipping deleted records)
#define RLUPTHIS(rp) for ( rp = (record *)( (char *)ptr() + eSz*mn ); \
rp <= (record *)( (char *)ptr() + eSz*n ); \
IncP( DMPP( rp), eSz) ) \
if (((record *)rp)->gud > 0)
if (((record *)rp)->r_status > 0)
//=============================================================================
#ifdef NEEDLIKECTOR // define where this constructor is USED: avoids generating for classes where not used.

Expand Down
4 changes: 3 additions & 1 deletion src/battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,10 @@ RC BATTERY::bt_DoHour(

// we divide by 2 because one full discharge and one full charge = one cycle
bt_cycles += fabs( dE_bt / bt_maxCap) / 2.f;

// accumulate to meter if requested
if (bt_meter)
MtrB.p[bt_meter].H.mtr_AccumEU(bt_endUse, P_bt * kW_to_btuh);
MtrB.p[bt_meter].H.bt += P_bt * kW_to_btuh;
}
else
{ // stage == 2 (after reports): copy current hour results to xxxlh
Expand Down
4 changes: 2 additions & 2 deletions src/cnah2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3940,13 +3940,13 @@ BOO AH::nxZn( ZNR *&zp) // first/next zone served by (having a terminal connect
// loop over zones / on reentry, start with zone AFTER last one returned

for (zp = zp ? zp + 1 : ZrB.p+ZrB.mn; zp <= ZrB.p + ZrB.n; zp++) // ** RLUP macro expanded & modified **
if (zp->gud > 0) // ..
if (zp->r_status > 0) // ..
{
TU *tu /*=NULL*/;
for (TI ui = zp->tu1; ui; ui = tu->nxTu4z) // search zone's TERMINALs for one served by airHandler
{
tu = TuB.p + ui;
if (tu->gud > 0) // insurance
if (tu->r_status > 0) // insurance
if (tu->ai==ss) // if TERMINAL is served by 'this' airHandler then ZONE is
return TRUE; // have first/next served zone
}
Expand Down
1 change: 0 additions & 1 deletion src/cncult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2265,7 +2265,6 @@ static CULT btT[] = //------ BATTERY cmd RAT Entry table, used from cnTopCult
//----------------- ----- --------------- ------- -- ------ ----- ------ ------ ---- ----
CULT( "*", STAR, 0, 0, 0, 0, 0, 0, 0.f, N, btStarCkf),
CULT( "btMeter", DAT, BATTERY_METER, 0, 0, VEOI, TYREF, &MtriB, N, N, N),
CULT( "btEndUse", DAT, BATTERY_ENDUSE, 0, 0, VEOI, TYCH, 0, C_ENDUSECH_BT, N, N),
CULT( "btChgEff", DAT, BATTERY_CHGEFF, 0, 0, VHRLY, TYFL, 0, 0.975f, N, N),
CULT( "btDschgEff", DAT, BATTERY_DSCHGEFF,0, 0, VHRLY, TYFL, 0, 0.975f, N, N),
CULT( "btMaxCap", DAT, BATTERY_MAXCAP, 0, 0, VEOI, TYFL, 0, 6.f, N, N),
Expand Down
16 changes: 9 additions & 7 deletions src/cncult2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ LOCAL RC topLr();
LOCAL RC topCon2();
LOCAL RC topFnd();
LOCAL RC topGt();
LOCAL RC topMtr();
LOCAL RC topMtr( int re);
LOCAL RC topGain();
LOCAL RC topRSys1();
LOCAL RC topRSys2();
Expand Down Expand Up @@ -278,7 +278,7 @@ LOCAL RC topCkfI( // finish/check/set up inner function
CSE_E( topZn( re) ) // do zones. E: returns if error.

//--- do meters early: ref'd by reports and maybe many other future things.
CSE_E( topMtr() ) // check/dup all types of meters (energy, dhw, air flow)
CSE_E( topMtr( re) ) // check/dup all types of meters (energy, dhw, air flow)

//--- do stuff re reports next -- much used even if error suppresses run. cncult4.cpp.
if (!re) // report/exports persist from autosize thru main simulation 6-95.
Expand Down Expand Up @@ -777,7 +777,7 @@ RC TOPRAT::brFileCk() // check/clean up inputs re binary results files, rob 12-2
//===========================================================================
/*virtual*/ void TOPRAT::Copy(const record* pSrc, int options/*=0*/)
{
if (gud) // if record already in use (eg 2nd run) (insurance). Note record must be constructed b4 operator=.
if (r_status) // if record already in use (eg 2nd run) (insurance). Note record must be constructed b4 operator=.
freeDM();

record::Copy( pSrc, options); // verifies class (rt) same, copies whole derived class record. ancrec.cpp.
Expand Down Expand Up @@ -1023,7 +1023,7 @@ ZNR::~ZNR() // zone runtime info record destructor
void ZNR::Copy( const record* pSrc, int options/*=0*/)
{
// first free pointed-to heap objects in destination
if (gud) // if a constructed record
if (r_status) // if a constructed record
{
dmfree( DMPP( rIgDist));
}
Expand Down Expand Up @@ -1484,7 +1484,9 @@ x }
return rc;
} // topGt
//===========================================================================
LOCAL RC topMtr() // check/dup all types of meters (energy, dhw, airflow)
LOCAL RC topMtr( // check/dup all types of meters (energy, dhw, airflow)
int re) // 0 = at RUN
// nz = 2nd call when main simulation follows autosize
// copy to run rat. Create sum-of-meters records as needed
{
RC rc{ RCOK };
Expand Down Expand Up @@ -1512,7 +1514,7 @@ LOCAL RC topMtr() // check/dup all types of meters (energy, dhw, airflow)
// checks must be done after refs are resolved
// (i.e. not at input time)
if (rc == RCOK)
rc = cgSubMeterSetup();
rc = cgSubMeterSetup( re);

return rc;
} // topMtr
Expand Down Expand Up @@ -1995,7 +1997,7 @@ RC ckRefPt( // check / access ref from one RAT to another
if (mbr <= 0 // min subscript is 1
|| mbr > toBase->n // bad if > max subscript in given RAT
|| ( p = &toBase->rec( mbr), // ok so far; point to record ...
p->gud <= 0) ) // bad if rec unused/bad (poss future)
p->r_status <= 0) ) // bad if rec unused/bad (poss future)
{
rc = badRefMsg( toBase, fromRec, mbr, mbrName, ownRec); // issue message, return bad
p = NULL;
Expand Down
Loading