@@ -266,7 +266,7 @@ struct DWHRUSE // info about 1 (shower) draw that could have DWHR
266266 DWHRUSE () : wdw_iFx( -1 ), wdw_coldCnx( 0 ), wdw_vol( 0 .f), wdw_volHR( 0 .f), wdw_temp( 0 .f)
267267 {}
268268 DWHRUSE ( int iFx, int coldCnx, float vol, float volHR, float temp)
269- : wdw_coldCnx( coldCnx), wdw_vol( vol), wdw_volHR( volHR), wdw_temp( temp)
269+ : wdw_iFx( iFx), wdw_coldCnx( coldCnx), wdw_vol( vol), wdw_volHR( volHR), wdw_temp( temp)
270270 {}
271271 ~DWHRUSE () {}
272272
@@ -1009,7 +1009,7 @@ void DHWSYS::ws_InitTicks( // initialize tick data for hour
10091009 ws_iTkNDWHR = -1 ;
10101010} // DHWSYS::ws_InitTicks
10111011// ----------------------------------------------------------------------------
1012- RC DHWSYS::ws_DoHourDWHR () // current hour DHWHEATREC modeling
1012+ RC DHWSYS::ws_DoHourDWHR () // current hour DHWHEATREC modeling (all DHWHEATRECs)
10131013{
10141014 RC rc = RCOK;
10151015
@@ -1024,62 +1024,86 @@ RC DHWSYS::ws_DoHourDWHR() // current hour DHWHEATREC modeling
10241024 // ws_qDWHR = 0.f; // total heat recovered by all DHWHEATREC devices, Btu
10251025 // ws_whUseNoHR = 0.; // check value: hour total hot water use w/o HR, gal
10261026 // init'd by caller
1027- double qRWHSum = 0 .;
1027+ double qRWHSum = 0 .; // hour total recovered heat to WH inlet, Btu
1028+ int multiDraw = 0 ;
10281029 // int nTk = Top.tp_NHrTicks();
10291030 for (int iTk=ws_iTk0DWHR; iTk < ws_iTkNDWHR; iTk++)
10301031 { DHWTICK& tk = ws_ticks[ iTk]; // DHWSYS tick info
10311032 if (tk.wtk_nHRDraws == 0 )
10321033 continue ; // no DHWHEATREC draws in this tick
1033- float vOther // non-DHWHEATREC draws that contribute to each
1034+ if (tk.wtk_nHRDraws > 1 )
1035+ multiDraw++;
1036+ float whUseOther = tk.wtk_whUse ;
1037+ float vHotOther // non-DHWHEATREC draws that contribute to each
10341038 // feedWH-DHWHEATREC potable-side vol
1035- = tk.wtk_whUse / max (ws_wrFeedWHCount, 1 );
1039+ = whUseOther / max (ws_wrFeedWHCount, 1 );
1040+ #if defined( _DEBUG)
1041+ int nReDo = 0 ; // debugging aid, see below
1042+ reDo:
1043+ #endif
10361044 float whUse = 0 .f ; // hot water use, this tick / all DHWHEATREC draws
10371045 float fxUseMix = 0 .f ; // mixed water use
10381046 float qR = 0 .f ; // tick heat recovered
10391047 float qRWH = 0 .f ; // tick heat recovered to WH feed
1048+ float whUseNoHR = 0 .f ; // tick hot water use w/o HR
10401049 DHWHEATREC* pWR;
10411050 RLUPC (WrR, pWR, pWR->ownTi == ss)
10421051 { DHWHRTICK& wrtk = pWR->wr_ticks [iTk]; // DHWHEATREC tick info
10431052 if (wrtk.wrtk_draws .size () > 0 )
10441053 whUse += pWR->wr_CalcTick ( this ,
10451054 wrtk, // tick info for *pWR
1046- vOther, // total non-HR hot water use, gal
1047- ws_whUseNoHR , fxUseMix, qR, qRWH); // results accum'd
1055+ vHotOther, // total non-HR hot water use, gal
1056+ whUseNoHR , fxUseMix, qR, qRWH); // results accum'd
10481057 }
1049- ws_AccumUseTick ( // accum to ws_tick, ws_whUse, and ws_fxMixUse
1050- C_DHWEUCH_SHOWER, iTk, fxUseMix, whUse);
1058+ #if defined( _DEBUG)
1059+ if (!nReDo)
1060+ #endif
1061+ ws_AccumUseTick ( // accum to ws_tick, ws_whUse, and ws_fxMixUse
1062+ C_DHWEUCH_SHOWER, iTk, fxUseMix, whUse);
1063+
1064+ // water heater inlet temp
10511065 float tO = ws_tInlet;
10521066 if (tk.wtk_whUse > 0 .)
10531067 tO += qRWH / (waterRhoCp * tk.wtk_whUse );
1054- #if defined( _DEBUG)
1055- else if (qRWH > 0 .f )
1056- printf (" \n Inconsistency: wtk_whUse=%0.3f qRWHWt=%0.3f" ,
1057- tk.wtk_whUse , qRWH);
1058- #endif
10591068 tk.wtk_tInletX = ws_AdjustTInletForSSF (tO);
1060- qRWHSum += qRWH;
1061- ws_qDWHR += qR; // accum to hour total heat recovered
1062- } // end tick
10631069
1064- #if 0 && defined( _DEBUG)
1065- if (frDiff( float( whUseTot), ws_whUse.total, .001f) > .001f)
1066- printf( "\nMismatch!");
1070+ #if defined( _DEBUG)
1071+ // tick energy balance
1072+ float qXNoHR = (whUseNoHR+whUseOther) * waterRhoCp * (ws_tUse - ws_tInlet);
1073+ float qX = tk.wtk_whUse * waterRhoCp * (ws_tUse - tO);
1074+ float qXHR = qX + qR;
1075+ if (frDiff (qXHR, qXNoHR, 1 .f ) > .001f )
1076+ {
1077+ printf (" \n DHWSYS '%s': ws_DoHourDWHR tick balance error (md=%d)" , name, multiDraw);
1078+ if (nReDo++ < 2 )
1079+ goto reDo; // repeat calc (debugging aid)
1080+ }
10671081#endif
1082+ ws_qDWHR += qR; // hour total heat recovered
1083+ qRWHSum += qRWH; // hour total heat to WH inlet
1084+ ws_whUseNoHR += whUseNoHR; // hour total WH use w/o HR
1085+
1086+ } // end tick
10681087
1069- // calc hour average adjusted inlet and hot water temps
1070- float tInletXNoSSF = ws_tInlet ;
1088+ // hour average adjusted inlet and hot water temps
1089+ float tInletXNoSSF;
10711090 if (qRWHSum > 0 .)
1072- { tInletXNoSSF = ws_tInlet + qRWHSum / (waterRhoCp * ws_whUse.total );
1073- ws_tInletX = ws_AdjustTInletForSSF ( tInletXNoSSF);
1091+ {
1092+ tInletXNoSSF = ws_tInlet + qRWHSum / (waterRhoCp * ws_whUse.total );
1093+ ws_tInletX = ws_AdjustTInletForSSF (tInletXNoSSF);
10741094 }
1095+ else
1096+ tInletXNoSSF = ws_tInlet;
10751097
10761098#if defined( _DEBUG)
1077- float qXNoHR = ws_whUseNoHR * waterRhoCp * (ws_tUse - ws_tInlet);
1099+ // hour energy balance
1100+ float qXNoHR = ws_whUseNoHR * waterRhoCp * (ws_tUse - ws_tInlet);
10781101 float qX = ws_whUse.total * waterRhoCp * (ws_tUse - tInletXNoSSF);
1079- if (frDiff (qX+ws_qDWHR, qXNoHR, 1 .f ) > .001f )
1080- printf ( " \n DHWSYS '%s': ws_DoHourDWHR balance error" , name);
1102+ float qXHR = qX + ws_qDWHR;
1103+ if (frDiff (qXHR, qXNoHR, 1 .f ) > .001f )
1104+ printf (" \n DHWSYS '%s': ws_DoHourDWHR balance error (md=%d)" , name, multiDraw);
10811105#endif
1082-
1106+
10831107 return rc;
10841108} // DHWSYS::ws_DoHourDWHR
10851109// ----------------------------------------------------------------------------
@@ -2702,7 +2726,7 @@ RC DHWHEATREC::wr_SetFXConnections(
27022726float DHWHEATREC::wr_CalcTick ( // calculate performance for 1 tick
27032727 DHWSYS* pWS, // parent DHWSYS
27042728 DHWHRTICK& wrtk, // current tick info for this DHWHEATREC
2705- float vOther, // hot water draws for other fixtures, gal
2729+ float vHotOther, // hot water draws for other fixtures, gal
27062730 // included in potable flow if feedsWH
27072731 float & whUseNoHR, // returned updated: hot water use w/o heat recovery, gal
27082732 // used re energy balance check
@@ -2711,40 +2735,26 @@ float DHWHEATREC::wr_CalcTick( // calculate performance for 1 tick
27112735 float & qRWH) // returned updated: tick recovered heat added to WH inlet water, Btu
27122736
27132737// returns hot water use for served fixtures, gal
2714- // (not including vOther )
2738+ // (not including vHotOther )
27152739{
27162740 int nD = wrtk.wrtk_draws .size ();
27172741 if (nD == 0 )
27182742 return 0 .f ; // no draws, no effect
27192743
2720- #if 0 && defined( _DEBUG)
2721- // if (Top.jDay == 91 && Top.iHr == 20)
2722- // printf(" Hit\n");
2723- static int nDMulti = 0;
2724- if (nD > 1)
2725- {
2726- if (nDMulti++ == 0)
2727- printf("\nMultiple draws: jDay=%d iH=%d",
2728- Top.jDay, Top.iHr);
2729- }
2730- else
2731- nDMulti = 0;
2732- #endif
2733-
27342744 // tick constants
27352745 float tpI = pWS->ws_tInlet ; // mains temp
27362746 float tHotFX = pWS->ws_tUse ; // hot water temp at fixture
27372747
27382748 float vd = 0 .f ; // total mixed use at all fixture(s), all draws, gal
27392749 // = drain volume
27402750 float tdI = 0 .f ; // average drain-side entering temp, F
2741- float vMixHR = 0 .f ; // total mixed use at fixtures with cold side
2751+ float vMixFXHR = 0 .f ; // total mixed use at fixtures with cold side
27422752 // connection to DHWHEATREC, gal
27432753 float vHotFX0= 0 .f ; // hot water req'd for fixtures that use
27442754 // mains water for mixing, gal
27452755
27462756 // re parallel potable-side DHWHEATRECs
2747- // caller allocates vOther equally to all feedsWH-DHWHEATREC(s) in DHWSYS
2757+ // caller allocates vHotOther equally to all feedsWH-DHWHEATREC(s) in DHWSYS
27482758 // >> DHWHEATER inlet flow for other draws assumed to flow equally via parallel paths
27492759 // this-DHWHEATREC fixture flows are assigned to this-DHWHEATREC potable flow
27502760 // >> this-DHWHEATER's fixtures DHWHEATER and tempering flows do NOT
@@ -2774,7 +2784,7 @@ float DHWHEATREC::wr_CalcTick( // calculate performance for 1 tick
27742784 else
27752785 // fixture cold comes from DHWHEATREC
27762786 // accum mixed vol, compute vHotFX below
2777- vMixHR += hru.wdw_vol ;
2787+ vMixFXHR += hru.wdw_vol ;
27782788 }
27792789 fxUseMix += vd; // accum to caller's total
27802790
@@ -2783,16 +2793,16 @@ float DHWHEATREC::wr_CalcTick( // calculate performance for 1 tick
27832793 tdI = bracket (tpI, tdI/max ( vd, .0001f ), tHotFX);
27842794
27852795
2786- float vp; // potable-side flow, gal
2787- float tpO = 0 .f ;// potable-side outlet temp, F
2788- float vHotFX; // fixture hot vol, gal
2796+ float vp = 0 . f ; // potable-side flow, gal
2797+ float tpO = 0 .f ; // potable-side outlet temp, F
2798+ float vHotFX = 0 . f ; // fixture hot vol, gal
27892799
2790- if (wr_FeedsFX ())
2800+ if (vMixFXHR > 0 . f ) // if any current draw feeds a fixture
27912801 {
27922802 // DHWHEATREC feeds fixture(s) and possibly WH
27932803 vp = wr_FeedsWH () // potable volume
2794- ? vMixHR + vHotFX0 + vOther // feeds both
2795- : vMixHR / 2 .f ; // fixture only: 1st guess
2804+ ? vMixFXHR + vHotFX0 + vHotOther // feeds both
2805+ : vMixFXHR / 2 .f ; // fixture only: 1st guess
27962806 int iL;
27972807 for (iL = 0 ; iL<10 ; iL++)
27982808 { // cold water temp at wdw_coldCnx fixture(s)
@@ -2808,7 +2818,7 @@ float DHWHEATREC::wr_CalcTick( // calculate performance for 1 tick
28082818 vHotFX += hru.wdw_vol * DHWMixF (hru.wdw_temp , tHotFX, tpO);
28092819 }
28102820 if (!wr_FeedsWH ())
2811- vp = vMixHR - vHotFX; // cold side flow
2821+ vp = vMixFXHR - vHotFX;
28122822
28132823#if 0 && defined( _DEBUG)
28142824 if (iL > 7)
@@ -2818,20 +2828,31 @@ float DHWHEATREC::wr_CalcTick( // calculate performance for 1 tick
28182828 break ;
28192829 wr_EffAdjusted (vp, tpI, vd, tdI); // update efficiency
28202830 }
2831+ vHotFX += vHotFX0; // total fixture hot water
28212832 }
28222833 else
2823- { // DWHR feeds WH only -- flows known
2824- vHotFX = vHotFX0;
2825- vp = vHotFX + vOther;
2826- wr_EffAdjusted (vp, tpI, vd, tdI); // derive wr_eff
2827- tpO = wr_HX (vp, tpI, vd, tdI);
2834+ { // no current fixture draw uses tempered cold-side water
2835+ // all flows known
2836+ vHotFX = vHotFX0; // hot water needed
2837+ if (wr_FeedsWH ())
2838+ { // potable side feeds water heater
2839+ // recovered heat boosts tInlet
2840+ vp = vHotFX + vHotOther;
2841+ wr_EffAdjusted (vp, tpI, vd, tdI); // derive wr_eff
2842+ tpO = wr_HX (vp, tpI, vd, tdI);
2843+ }
2844+ else
2845+ { // does not feed WH
2846+ // no heat recovered
2847+ vp = 0 .f ; // no potable-side flow
2848+ tpO = tpI; // outlet temp = inlet temp (insurance)
2849+ }
28282850 }
28292851
28302852 float qR1 = vp * waterRhoCp * (tpO - tpI); // recovered heat
28312853 qR += qR1;
2832- qRWH += wr_FeedsWH () && vp > 0 .f // recovered heat to WH
2833- ? qR1 * (vHotFX + vOther) / vp
2834- : 0 .f ;
2854+ if (wr_FeedsWH () && vp > 0 .f )
2855+ qRWH += qR1 * (vHotFX + vHotOther) / vp; // recovered heat to WH
28352856 return vHotFX;
28362857
28372858} // DHWHEATREC::wr_CalcTick
0 commit comments