Skip to content

Commit f0de00b

Browse files
authored
Merge pull request #441 from cse-sim/airnet-msg-control
AirNet pressure warnings/errors: add user input / refine logic
2 parents 07b7e4c + bfaaf9b commit f0de00b

File tree

12 files changed

+563
-186
lines changed

12 files changed

+563
-186
lines changed

doc/src/records/top-members.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,29 @@ AirNet relative convergence tolerance. See AnTolAbs just above.
411411
required: "No",
412412
variability: "constant") %>
413413

414+
**ANPressWarn=*float***
415+
416+
AirNet pressure warning threshold. A warning message is issued when the absolute value of the AirNet-calculated zone pressure exceeds ANPressWarn. Note the default for ANPressWarn conservatively large. 10 lb/ft2 is about 500 pascals -- a pressure that is probably impossible in a building. The intent of this value is to alert the user to incorrect modeling inputs while avoiding excessive messages.
417+
418+
<%= member_table(
419+
units: "lb/ft2",
420+
legal_range: "x $\\gt$ 0",
421+
default: "10",
422+
required: "No",
423+
variability: "constant") %>
424+
425+
**ANPressErr=*float***
426+
427+
AirNet pressure error threshold. The simulation terminates with a message if the absolute value of any AirNet-calculated zone pressure exceeds ANPressErr. Note the default value for ANPressErr is physically unrealistic. 30 lb/ft2 is about 1500 pascals -- a pressure that would never be possible in a building. The intent of this value is to prevent simulation crashes due to numerical errors in AirNet calculations.
428+
429+
<%= member_table(
430+
units: "lb/ft2",
431+
legal_range: "x $\\gt$ 0",
432+
default: "30",
433+
required: "No",
434+
variability: "constant") %>
435+
436+
414437
The ASHWAT complex fenestration model used when WINDOW wnModel=ASHWAT yields several heat transfer results that are accurate over local ranges of conditions. Several values control when these value are recalculated. If any of the specified values changes more than the associated threshold, a full ASHWAT calculation is triggered. Otherwise, prior results are used. ASHWAT calculations are computationally expensive and conditions often change only incrementally between time steps.
415438

416439
**AWTrigT=*float***

src/CNRECS.DEF

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,16 @@ RECORD TOPRAT "top" *RAT /* top level RAT: contains control info and all once-on
130130
*ovrcopy
131131
*declare "void freeDM();"
132132
*declare "const char* When( IVLCH ivl) const;"
133-
*declare "int tp_IsLastStep() const { return isLastDay && isEndDay && isEndHour; }" // TRUE iff last step of run
134-
*declare "int tp_IsLastHour() const { return isLastDay && isEndDay; }"
133+
*declare "bool tp_IsLastStep() const { return isLastDay && isEndDay && isEndHour; }" // true iff last step of run
134+
*declare "bool tp_IsLastHour() const { return isLastDay && isEndDay; }"
135135
*declare "RC FC brFileCk();" // checks inputs re binary results files.
136136
*declare "RC tp_CheckOutputFilePath( const char* filePath, const char** pMsg=NULL);"
137137
*declare "void tp_SetOptions();"
138138
*declare "RC tp_SetDerived();"
139139
*declare "RC tp_SetCheckTimeSteps();"
140140
*declare "RC tp_FazInit();"
141+
*declare "RC tp_AirNetInit();"
142+
*declare "void tp_AirNetDestroy();"
141143
*declare "void tp_ClearAuszFlags();"
142144
*declare "RC tp_Wfile( int* pHotMo);"
143145
*declare "RC tp_LocInit();"
@@ -233,11 +235,13 @@ RECORD TOPRAT "top" *RAT /* top level RAT: contains control info and all once-on
233235
*i FLOAT_GZ tp_AWTrigSlr; // incident solar, fraction (default = .05)
234236
*i FLOAT_GZ tp_AWTrigH; // total surface coefficient (conv+rad), fraction (default=.1)
235237

236-
//TOP: inputs: AirNet convergence criteria
238+
//TOP: inputs: AirNet convergence and error criteria
237239
// a zone is deem converged iff
238240
// AMFnet <= max( tolAbs, tolRel*AMFTot)
239241
*i FLOAT_GZ tp_ANTolAbs; // absolute tolerance, lbm/sec, dflt=.00125 (about 1 cfm)
240242
*i FLOAT_GZ tp_ANTolRel; // relative tolerance, dflt = .0001
243+
*i FLOAT_GZ tp_ANPressWarn; // AirNet pressure that triggers a warning, lb/ft2
244+
*i FLOAT_GZ tp_ANPressErr; // AirNet pressure that triggers a run-ending error, lb/ft2
241245

242246
//TOP: inputs: other
243247
*i ANGLE tp_bldgAzm // angle to add to all zone/surface azms
@@ -2225,6 +2229,7 @@ RECORD ZNR "zone" *RAT // zone runtime info RAT. Set mainly from separate ZNI
22252229
*declare "RC zn_RadX();"
22262230
*declare "RC zn_FFactors( struct SFPLIST& sfpList);"
22272231
*declare "RC zn_RddInit();"
2232+
*declare "RC zn_RddDone( bool isAusz);"
22282233
*declare "RC zn_BegHour1();"
22292234
*declare "RC zn_BegHour2();"
22302235
*declare "RC zn_XFan();"
@@ -2455,6 +2460,9 @@ RECORD ZNR "zone" *RAT // zone runtime info RAT. Set mainly from separate ZNI
24552460
// [ 1]=maximum (generally infil+vent)
24562461
*s *e *array 2 DBL zn_pz0W // working zone pressures relative to patm at nominal z=0, lbf/sf
24572462
// [ 0]=infil only; [ 1]=infil+ven
2463+
*y *e *array 2 INT zn_pz0WarnCount; // # of unreasonable pressure warnings issued for this zone
2464+
// [0]=infil only; [1]=infil+vent
2465+
*declare "RC zn_CheckAirNetPressure( int iV);"
24582466
#if 0 // unused idea
24592467
0 *declare "float zn_GetPressureAtFloorZ( int iV) const { return zn_pz0W[ iV] - i.zn_floorZ*zn_rho; }"
24602468
#endif

src/cgcomp.cpp

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,33 @@ RC IZXRAT::iz_EndSubhr() // end-of-subhour vent calcs
22512251
} // IZXRAT::iz_EndSubhr
22522252
//=============================================================================
22532253

2254+
///////////////////////////////////////////////////////////////////////////////
2255+
// Check / initialize for AirNet calcs
2256+
///////////////////////////////////////////////////////////////////////////////
2257+
RC TOPRAT::tp_AirNetInit()
2258+
{
2259+
2260+
RC rc = RCOK;
2261+
2262+
// AIRNET msg triggers
2263+
if (Top.tp_ANPressWarn >= Top.tp_ANPressErr)
2264+
rc |= err("ANPressWarn (%0.1f) must be less than ANPressErr (%0.1f)", Top.tp_ANPressWarn, Top.tp_ANPressErr);
2265+
2266+
tp_pAirNet = new AIRNET();
2267+
2268+
return rc;
2269+
2270+
} // TOPRAT::tp_AirNetInit
2271+
//-----------------------------------------------------------------------------
2272+
void TOPRAT::tp_AirNetDestroy()
2273+
// redundant calls OK
2274+
{
2275+
delete tp_pAirNet;
2276+
tp_pAirNet = NULL;
2277+
2278+
} // TOPRAT::to_AirNetDestroy
2279+
//=============================================================================
2280+
22542281
///////////////////////////////////////////////////////////////////////////////
22552282
// struct AIRNET
22562283
// finds zone pressures that achieve balanced mass flows
@@ -2538,6 +2565,15 @@ RC AIRNET_SOLVER::an_Calc( // airnet flow balance
25382565
if (!bConverge)
25392566
err(WRN, "%s: AirNet convergence failure", Top.When(C_IVLCH_S));
25402567

2568+
// change tiny pressures to 0
2569+
// prevents trouble when doubles assigned to floats
2570+
for (zi = 0; zi < an_nz; zi++)
2571+
{
2572+
ZNR* zp = ZrB.GetAt(zi + zi0);
2573+
if (fabs(zp->zn_pz0W[iV]) < 1.e-20)
2574+
zp->zn_pz0W[iV] = 0.;
2575+
}
2576+
25412577
rc = RCOK;
25422578

25432579
TMRSTOP(TMR_AIRNET);
@@ -2548,33 +2584,60 @@ RC AIRNET_SOLVER::an_Calc( // airnet flow balance
25482584
RC AIRNET_SOLVER::an_CheckResults(
25492585
int iV) // mode (0 or 1)
25502586
{
2551-
static constexpr int MAXANERRORS = 100;
25522587

25532588
RC rc = RCOK;
2554-
if (an_unreasonablePressureCount >= MAXANERRORS)
2555-
return RCBAD; // no further messages
2556-
2589+
25572590
int zi0 = ZrB.GetSS0();
25582591
for (int zi = 0; zi < an_nz; zi++)
2559-
{
2560-
ZNR* zp = ZrB.GetAt(zi + zi0);
2561-
if (fabs(zp->zn_pz0W[iV]) > 10.)
2562-
{ // zone pressure > 10 lb/ft2 (= 500 Pa approx)
2563-
// notify user
2564-
// ignore during early autosizing --
2565-
// transient unreasonable values have been seen
2566-
if (!Top.tp_autoSizing || Top.tp_pass2)
2567-
{
2568-
warn(
2569-
"Zone '%s', %s: unreasonable mode %d pressure %0.2f lb/ft2\n",
2570-
zp->Name(), Top.When(C_IVLCH_S), iV, zp->zn_pz0W[iV]);
2571-
if (++an_unreasonablePressureCount == MAXANERRORS)
2572-
rc = err("Too many unreasonable zone pressures, abandoning run.");
2573-
}
2574-
}
2592+
{ ZNR* zp = ZrB.GetAt(zi + zi0);
2593+
rc |= zp->zn_CheckAirNetPressure(iV);
25752594
}
2595+
2596+
// note zn_pz0WarnCount is reported in zn_RddDone()
2597+
25762598
return rc;
25772599
} // AIRNET_SOLVER::an_CheckResults
2600+
//-----------------------------------------------------------------------------
2601+
RC ZNR::zn_CheckAirNetPressure( // check zone pressure for reasonableness
2602+
int iV) // mode (0 or 1)
2603+
2604+
// checks zone pressure against tp_ANPressWarn and tp_anPressErr
2605+
2606+
// returns RCOK iff run should continue
2607+
// RCBAD if error, run should stop
2608+
2609+
{
2610+
static constexpr int MAXANWARNINGMSGS = 50; // max warning messages per zone
2611+
2612+
RC rc = RCOK;
2613+
double pz0Abs = fabs( zn_pz0W[iV]);
2614+
if (pz0Abs > Top.tp_ANPressWarn)
2615+
{ // zone pressure > user-settable threshold
2616+
// notify user
2617+
// ignore during early autosizing --
2618+
// transient unreasonable values have been seen
2619+
if (pz0Abs > Top.tp_ANPressErr)
2620+
{ // set rc to stop run
2621+
rc |= orer("mode %d pressure (%0.2f lb/ft2) exceeds ANPressErr (+/- %0.2f lb/ft2)."
2622+
"\n Abandoning run.",
2623+
iV, zn_pz0W[iV], Top.tp_ANPressErr);
2624+
}
2625+
else if (!Top.tp_autoSizing || Top.tp_pass2)
2626+
{
2627+
++zn_pz0WarnCount[iV];
2628+
if (zn_pz0WarnCount[iV] <= MAXANWARNINGMSGS)
2629+
// do not set rc
2630+
orWarn("unreasonable mode %d pressure %0.2f lb/ft2%s",
2631+
iV, zn_pz0W[iV],
2632+
zn_pz0WarnCount[iV] == MAXANWARNINGMSGS
2633+
? "\n Skipping further pressure warning messages for this zone/mode."
2634+
: "");
2635+
2636+
}
2637+
}
2638+
2639+
return rc;
2640+
} // ZNR::zn_CheckAirNetPressure
25782641
//=============================================================================
25792642
#else
25802643
AIRNET::AIRNET()

src/cnausz.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ RC FC cgAusz() // Autosizing entry point
126126
Top.tp_ClearAuszFlags(); // error return insurance
127127

128128
// end phase (autosize or main sim) stuff done even after initialization or run error
129-
RC rc2 = cgRddDone(TRUE); // cleanup also done (from tp_EndDesDay) after each design day. Redundant call ok. cnguts.cpp.
130-
rc2 |= cgFazDone(TRUE); // cleanup done once after all design days. cnguts.cpp. Empty fcn 7-95.
129+
RC rc2 = cgRddDone( true); // cleanup also done (from tp_EndDesDay) after each design day. Redundant call ok. cnguts.cpp.
130+
rc2 |= cgFazDone( true); // cleanup done once after all design days. cnguts.cpp. Empty fcn 7-95.
131131
return rc ? rc : rc2; // return exact rc from cgAuszI re ^C detection
132132
} // cgAusz
133133
//-----------------------------------------------------------------------------------------------------------
@@ -147,7 +147,7 @@ LOCAL RC FC cgAuszI() // Autosizing inner routine
147147
// If not verbose, continues line started in cse.cpp.
148148
Top.tp_ClearAuszFlags();
149149

150-
CSE_EF( cgFazInit(TRUE)); // do initialization done once for all design days:
150+
CSE_EF( cgFazInit( true)); // do initialization done once for all design days:
151151
// Inits autoSizing & peak recording stuff in all objects.
152152
// Calls AH::, TU::, HEATPLANT:: etc fazInit's, which call AUSZ::fazInit's
153153
// (below, sets .az_px's, etc) & do addl object-specific init.
@@ -204,7 +204,7 @@ RC TOPRAT::tp_BegDesDay() // init many things before start of repetitions for de
204204

205205
// init simulator to stardard state before each design day -- 70F zone temps, etc.
206206
RC rc;
207-
CSE_E( cgRddInit(TRUE));// init repeated for (main sim run or) each autoSize design day, cnguts.cpp.
207+
CSE_E( cgRddInit( true));// init repeated for (main sim run or) each autoSize design day, cnguts.cpp.
208208
// sets initial state of zones & systems; calls AH::rddInit's, etc.
209209
// also allocs results records not used in autosizing, etc, ... .
210210
// calls asRddiInit in this file: clears peaks.
@@ -258,7 +258,7 @@ RC TOPRAT::tp_EndDesDay() // call when done with design day
258258
tp_auszDsDayItr = tp_auszDsDayItrMax = 0; // used eg in exman.cpp::rerIV
259259

260260
// end run stuff: close weather file, import files, binRes, location, etc. cnguts.cpp.
261-
RC rc = cgRddDone(TRUE); // may also be called at completion of phase; redundant call ok.
261+
RC rc = cgRddDone( true); // may also be called at completion of phase; redundant call ok.
262262

263263
return rc;
264264
} // TOPRAT::tp_EndDesDay
@@ -710,10 +710,9 @@ LOCAL WStr MakeNotDoneList()
710710
//===========================================================================================================
711711
// cse MAIN SIMULATION support function(s) that use AUSZ stuff
712712
//===========================================================================================================
713-
RC FC asFazInit([[maybe_unused]] int isAusz) // main sim run or autoSize phase init: portion in this file
713+
RC FC asFazInit([[maybe_unused]] bool isAusz) // main sim run or autoSize phase init: portion in this file
714714

715715
{
716-
// caller: cnguts:cgFazInit() 6-95
717716
return RCOK; // empty fcn, 7-95
718717
} // asFazInit
719718
//-----------------------------------------------------------------------------------------------------------

src/cncult.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2783,9 +2783,12 @@ CULT cnTopCult[] = // Top level table, points to all other tables, used in cal
27832783
CULT( "AWTrigT", DAT, TOPRAT_AWTRIGT, 0, 0, VEOI, TYFL, 0, 1.f, N, N),
27842784
CULT( "AWTrigSlr", DAT, TOPRAT_AWTRIGSLR, 0, 0, VEOI, TYFL, 0, .05f, N, N),
27852785
CULT( "AWTrigH", DAT, TOPRAT_AWTRIGH, 0, 0, VEOI, TYFL, 0, .1f, N, N),
2786-
// TOP AirNet convergence tolerances (1-2015)
2786+
// TOP AirNet convergence tolerances and msg thresholds
27872787
CULT( "ANTolAbs", DAT, TOPRAT_ANTOLABS, 0, 0, VEOI, TYFL, 0, 0.00125f, N, N),
27882788
CULT( "ANTolRel", DAT, TOPRAT_ANTOLREL, 0, 0, VEOI, TYFL, 0, 0.0001f, N, N),
2789+
CULT( "ANPressWarn", DAT, TOPRAT_ANPRESSWARN,0, 0, VEOI, TYFL, 0, 10.f, N, N),
2790+
CULT( "ANPressErr", DAT, TOPRAT_ANPRESSERR, 0, 0, VEOI, TYFL, 0, 30.f, N, N),
2791+
27892792
// TOP other
27902793
CULT( "bldgAzm", DAT, TOPRAT_BLDGAZM, 0, 0, VEOI, TYFL, 0, 0.f, N, N),
27912794
CULT( "skymodel", DAT, TOPRAT_SKYMODEL, 0, 0, VEOI, TYCH, 0, C_SKYMODCH_ANISO, N, N),

src/cncult2.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -455,20 +455,21 @@ RC TOPRAT::tp_FazInit() // start-of-phase init
455455
#if defined( DEBUGDUMP)
456456
DbDo(dbdSTARTRUN); // init debug print scheme (re heading control)
457457
tp_SetDbMask(); // debug printout mask (dbdXXX), controls internal val dumping
458-
// (can change hourly, set initial value here re print from setup code)
458+
// (can change hourly, set initial value here re print from setup code)
459459
#endif
460460

461461
//---- find/read weather file name / get lat, long, tz, default elevation, default autosizing stuff. 1-95.
462462
int hotMo = 7; // hottest month 1-12, wthr file hdr to topAusz, July if not set by topWfile
463463
CSE_E(tp_Wfile(&hotMo)) // just below. call b4 topAusz.
464464

465-
//---- autosizing setup. call after topWfile. 6-95.
466-
CSE_E(tp_Ausz(hotMo))
465+
//---- autosizing setup. call after topWfile. 6-95.
466+
CSE_E(tp_Ausz(hotMo))
467467

468-
//---- say various texts should be (re)generated before (any further) use as may have new runTitle, repHdrL/R.
469-
freeRepTexts(); // cncult4.cpp
468+
//---- say various texts should be (re)generated before (any further) use as may have new runTitle, repHdrL/R.
469+
freeRepTexts(); // cncult4.cpp
470470

471-
tp_pAirNet = new AIRNET();
471+
// check and set up AIRNET
472+
rc |= tp_AirNetInit();
472473

473474
return rc;
474475
} // TOPRAT::tp_fazInit
@@ -827,8 +828,7 @@ void TOPRAT::freeDM() // free child objects in DM
827828
tp_brFileName.Release();
828829
#endif
829830

830-
delete tp_pAirNet;
831-
tp_pAirNet = NULL;
831+
tp_AirNetDestroy(); // cleanup / delete AirNet machinery
832832

833833
tp_PumbraDestroy(); // cleanup / delete Penumbra shading machinery
834834

0 commit comments

Comments
 (0)