diff --git a/doc/src/records/dhwheater-doc.md b/doc/src/records/dhwheater-doc.md index 6f6c0eb72..7818b6e90 100644 --- a/doc/src/records/dhwheater-doc.md +++ b/doc/src/records/dhwheater-doc.md @@ -225,7 +225,9 @@ Instanteous water heater load carry forward factor -- approximate number of hour **whZone=*znName*** -Name of zone where water heater is located, used only in detailed HPWH models (whHeatSrc=ASHPX or whHeatSrc=RESISTANCEX), otherwise no effect. Zone conditions are used for tank heat loss calculations. Heat exchanged with the DHWHEATER are included in the zone heat balance. whZone also provides the default for whASHPSrcZn (see below). whZone and whTEx cannot both be specified. +Name of zone where water heater is located, used only in detailed HPWH models (whHeatSrc=ASHPX or whHeatSrc=RESISTANCEX), otherwise no effect. Zone conditions are used for tank heat loss calculations. Heat losses from the DHWHEATER are included in the zone heat balance. whZone also provides the default for whASHPSrcZn (see below). + +whZone and whTEx cannot both be specified. <%= member_table( units: "", @@ -237,7 +239,9 @@ Name of zone where water heater is located, used only in detailed HPWH models (w **whTEx=*float*** -Water heater surround temperature, used only in detailed HPWH models (whHeatSrc=ASHPX or whHeatSrc=RESISTANCEX), otherwise no effect. whZone and whTEx cannot both be specified. +Water heater surround temperature, used only in detailed HPWH models (whHeatSrc=ASHPX or whHeatSrc=RESISTANCEX), otherwise no effect. When whTEx is specified, tank heat losses are calculated using whTEx and modify tank water temperatures, but the lost heat has no external effect. + +whZone and whTEx cannot both be specified. <%= member_table( units: "^o^F", @@ -285,6 +289,12 @@ Air source heat pump type, valid only if whHeatSrc=ASHPX. These choices are supp "Rheem2020Build50","50 gallon, Rheem 2020 Builder" "Rheem2020Build65","65 gallon, Rheem 2020 Builder" "Rheem2020Build80","80 gallon, Rheem 2020 Builder" +"RheemPlugInShared40","40 gal Rheem plug-in 120V shared circuit (no resistance elements)" +"RheemPlugInShared50","50 gal Rheem plug-in 120V shared circuit (no resistance elements)" +"RheemPlugInShared65","65 gal Rheem plug-in 120V shared circuit (no resistance elements)" +"RheemPlugInShared80","80 gal Rheem plug-in 120V shared circuit (no resistance elements)" +"RheemPlugInDedicated40","40 gal Rheem plug-in 120V dedicated circuit (no resistance elements)" +"RheemPlugInDedicated50","50 gal Rheem plug-in 120V dedicated circuit (no resistance elements)" "Stiebel220E","Stiebel Eltron (2014 model?)" "AOSmithSHPT50","AOSmith add'l models (added 3-24-2017)" "AOSmithSHPT66","AOSmith add'l models (added 3-24-2017)" @@ -354,24 +364,43 @@ END **whASHPSrcZn=*znName*** -Name of zone that serves as heat pump heat source used when whHeatSrc=ASHPX. Used for tank heat loss calculations and default for whASHPSrcZn. Heat exchanges are included in zone heat balance. whASHPSrcZn and whASHPSrcT cannot both be specified. +Name of zone that serves as heat pump heat source used when whHeatSrc=ASHPX. Heat removed from the zone is added to the heated water and is included in zone heat balance (that is, heat pump operation cools the zone). + +whASHPSrcZn and whASHPSrcT cannot both be specified. <%= member_table( units: "", legal_range: "name of a ZONE", - default: "Same as whZone not specified. If no zone is specified by input or default, heat extracted by ASHP has no effect.", + default: "whZoneIf no zone is specified by input or default, heat extracted by ASHP has no effect.", required: "No", variability: "constant") %> **whASHPSrcT=*float*** -Heat pump source air temperature used when whHeatSrc=ASHPX. Heat removed from this source is added to the heated water but has no other effect. whASHPSrcZn and whASHPSrcT cannot both be specified. +Heat pump source air temperature used when whHeatSrc=ASHPX. Heat removed from this source is added to the heated water but has no other effect. + +whASHPSrcZn and whASHPSrcT cannot both be specified. + +The logic to determine the temperature of the heat pump source air is: + +~~~ + if whASHPSrcT is specified + use whASHPSrcT + else if whASHPSRCZn is specified + use whASHPSrcZn air temp + else if whZone is specified + use whZone air temp + else + use 70 F +~~~ + +To model a heat pump that uses outdoor air as its heat source, omit whASHPSrcZn and specify whASHPSrcT = $tDbO. <%= member_table( units: "^o^F", legal_range: "x $\\ge$ 0", - default: "whASHPZn air temperature if specified, else 70 ^o^F", + default: "70 ^o^F (used only when whASHPSrcZn and whZone not specified)", required: "No", variability: "hourly") %> diff --git a/doc/src/records/rsys.md b/doc/src/records/rsys.md index 1e0e9e07f..bd20e0b44 100644 --- a/doc/src/records/rsys.md +++ b/doc/src/records/rsys.md @@ -137,9 +137,15 @@ Name of METER object, if any, by which system’s fuel energy use is recorded (u required: "No", variability: "constant") %> -**rsLoadMtr =*ldmtrName*** +**rsLoadMtr =*ldMtrName***\ +**rsHtgLoadMtr =*ldMtrName***\ +**rsClgLoadMtr =*ldMtrName*** -Name of a LOADMETER object, if any, to which the system’s heating and cooling loads are recorded. Loads are the gross heating and cooling energy added to (or removed from) the air stream. Fan heat, auxiliary heat, and duct losses are not included in loads values. +Names of LOADMETER objects, if any, to which the system’s heating and/or cooling loads are recorded. Loads are the gross heating and cooling energy added to (or removed from) the air stream. Fan heat, auxiliary heat, and duct losses are not included in loads values. + +rsLoadMtr accumulates both heating (> 0) and cooling (< 0) loads. rsHtgLoadMtr accumulates only heating loads. rsClgLoadMtr accumulates only cooling loads. This arrangement accomodates mixed heating and cooling source configurations. For example, loads can be tracked appropriately in a building that has multiple cooling sources and a single heating source. + +rsLoadMtr should not specify the same LOADMETER as rsHtgLoadMtr or rsClgLoadMtr since this would result in double counting. <%= member_table( units: "", @@ -148,13 +154,19 @@ Name of a LOADMETER object, if any, to which the system’s heating and cooling required: "No", variability: "constant") %> -**rsSrcSideLoadMtr=*ldMtrName*** +**rsSrcSideLoadMtr=*ldMtrName***\ +**rsHtgSrcSideLoadMtr =*ldMtrName***\ +**rsClgSrcSideLoadMtr =*ldMtrName*** + +Name of LOADMETER objects, if any, to which the system’s source-side heat transfers are recorded. For DX systems, this is the outdoor coil heat transfer. For other types, source-side values are the same as the indoor coil loads reported via rsLoadMtr. + +rsSrcSideLoadMtr accumulates both heating (> 0) and cooling (< 0) transfers. rsHtgSrcSideLoadMtr accumulates only heating transfers. rsClgSrcSideLoadMtr accumulates only cooling transfers. This arrangement accomodates mixed heating and cooling source configurations. -Name of a LOADMETER object, if any, to which the system’s source-side heat (heat of rejection or outdoor coil heat transfer) are recorded. +rsSrcSideLoadMtr should not specify the same LOADMETER as rsHtgSrcSideLoadMtr or rsClgSrcSideLoadMtr since this would result in double counting. <%= member_table( units: "", - legal_range: "*Name of ldMtrName*", + legal_range: "*Name of a LOADMETER*", default: "", required: "No", variability: "constant") %> diff --git a/src/CNRECS.DEF b/src/CNRECS.DEF index 1b65ec963..12e2119ca 100644 --- a/src/CNRECS.DEF +++ b/src/CNRECS.DEF @@ -3387,19 +3387,22 @@ x *declare "RC rs_SetDefaultsClg();" *i TI rs_elecMtri // meter for system electricity use *i TI rs_fuelMtri // meter for system fuel use -*i TI rs_loadMtri // LOADMTR idx for accumulation of primary (coil) output +*i TI rs_loadMtri // idx of LOADMETER that accumulates of primary (coil) output // qHtg accums heating output, Btu (> 0) // qClg accums cooling output, Btu (< 0) -*i TI rs_srcSideLoadMtri // LOADMTR idx for accumulation of source-side heat +*i TI rs_htgLoadMtri // idx of LOADMETER that accumulates only primary (coil) heating output +*i TI rs_clgLoadMtri // idx of LOADMETER that accumulates only primary (coil) cooling output +*i TI rs_srcSideLoadMtri // idx of LOADMETER that accumulation of source-side heat transfer // aka heat of rejection or outdoor coil heat transfer // qHtg accums heat to RSYS from env during heating operation, Btu (> 0) // qClg accums heat from RSYS to env during cooling opersion, Btu (< 0) // Meaningful for compression rs_types. -*declare "MTR* rs_pMtrElec; MTR* rs_pMtrFuel; MTR* rs_pMtrHeat; MTR* rs_pMtrAux; LOADMTR* rs_pLoadMtr; LOADMTR* rs_pSrcSideLoadMtr;" +*i TI rs_htgSrcSideLoadMtri // idx of LOADMETER for accumulation of source-side heating +*i TI rs_clgSrcSideLoadMtri // idx of LOADMETER for accumulation of source-side cooling +*declare "MTR* rs_pMtrElec; MTR* rs_pMtrFuel; MTR* rs_pMtrHeat; MTR* rs_pMtrAux; LOADMTR* rs_pLoadMtr[ 3]; LOADMTR* rs_pSrcSideLoadMtr[ 3];" // runtime pointers to meters, NULL if not accum'ing // rs_pMtrAux either elec or fuel per rs_typeAuxH - // parasitic consumption: accum'd to Par end use in // appropriate meter; no thermal effect *h FLOAT rs_parElec // electrical parasitic power, W diff --git a/src/cncult.cpp b/src/cncult.cpp index 16a594c7f..bd56045b6 100644 --- a/src/cncult.cpp +++ b/src/cncult.cpp @@ -1601,7 +1601,11 @@ CULT( "rsModeCtrl", DAT, RSYS_MODECTRL, 0, 0, VHRLY, TYCH, 0, C_ CULT( "rsElecMtr", DAT, RSYS_ELECMTRI, 0, 0, VEOI, TYREF, &MtriB, N, N, N), CULT( "rsFuelMtr", DAT, RSYS_FUELMTRI, 0, 0, VEOI, TYREF, &MtriB, N, N, N), CULT( "rsLoadMtr", DAT, RSYS_LOADMTRI, 0, 0, VEOI, TYREF, &LdMtriB, N, N, N), +CULT( "rsHtgLoadMtr",DAT, RSYS_HTGLOADMTRI,0, 0, VEOI, TYREF, &LdMtriB, N, N, N), +CULT( "rsClgLoadMtr",DAT, RSYS_CLGLOADMTRI,0, 0, VEOI, TYREF, &LdMtriB, N, N, N), CULT( "rsSrcSideLoadMtr", DAT, RSYS_SRCSIDELOADMTRI, 0,0,VEOI, TYREF, &LdMtriB, N, N, N), +CULT( "rsHtgSrcSideLoadMtr",DAT,RSYS_HTGSRCSIDELOADMTRI,0,0,VEOI,TYREF, &LdMtriB, N, N, N), +CULT( "rsClgSrcSideLoadMtr",DAT,RSYS_CLGSRCSIDELOADMTRI,0,0,VEOI,TYREF, &LdMtriB, N, N, N), CULT( "rsTdDesH", DAT, RSYS_TDDESH, 0, 0, VEOI, TYFL, 0, 50.f, N, N), CULT( "rsTdDesC", DAT, RSYS_TDDESC, 0, 0, VEOI, TYFL, 0, -25.f, N, N), CULT( "rsFxCapH", DAT, RSYS_FXCAPHTARG, 0, 0, VEOI, TYFL, 0, 1.4f, N, N), diff --git a/src/cnloads.cpp b/src/cnloads.cpp index d35cadcd1..d8ebb6b38 100644 --- a/src/cnloads.cpp +++ b/src/cnloads.cpp @@ -3101,8 +3101,12 @@ void RSYS::rs_SetMTRPtrs() // set runtime pointers to meters rs_pMtrFuel = MtrB.GetAtSafe( rs_fuelMtri); // fuel mtr or NULL rs_pMtrHeat = rs_IsElecHeat() ? rs_pMtrElec : rs_pMtrFuel; // heat mtr or NULL rs_pMtrAux = rs_IsFuelAuxH() ? rs_pMtrFuel : rs_pMtrElec; - rs_pLoadMtr = LdMtrR.GetAtSafe(rs_loadMtri); - rs_pSrcSideLoadMtr = LdMtrR.GetAtSafe(rs_srcSideLoadMtri); + rs_pLoadMtr[ 0] = LdMtrR.GetAtSafe(rs_loadMtri); + rs_pLoadMtr[ 1] = LdMtrR.GetAtSafe(rs_htgLoadMtri); + rs_pLoadMtr[ 2] = LdMtrR.GetAtSafe(rs_clgLoadMtri); + rs_pSrcSideLoadMtr[ 0] = LdMtrR.GetAtSafe(rs_srcSideLoadMtri); + rs_pSrcSideLoadMtr[ 1] = LdMtrR.GetAtSafe(rs_htgSrcSideLoadMtri); + rs_pSrcSideLoadMtr[ 2] = LdMtrR.GetAtSafe(rs_clgSrcSideLoadMtri); } // RSYS::rs_SetMTRPtrs //----------------------------------------------------------------------------- RC RSYS::rs_SetupSizes( // derive capacity-dependent values @@ -3363,6 +3367,7 @@ RC RSYS::rs_EndSubhr() } // populate results + // Note: MTRs and LOADMTs are cleared in ::doBegIvl() RSYSRES_IVL_SUB& R = RsResR[ ss].curr.S; R.fhTot = R.fhParasitic = rs_parFuel * Top.tp_subhrDur; // assign fuel parasitics to heating @@ -3406,11 +3411,16 @@ RC RSYS::rs_EndSubhr() /* + R.ehParasitic see above */ R.fhTot += R.fhPrimary + R.fhDefrost + R.fhAux /* + R.fhParasitic*/; - if (rs_pLoadMtr) // primary LOADMTR (= indoor coil) - rs_pLoadMtr->S.qHtg += R.qhPrimary; - if (rs_pSrcSideLoadMtr) // source-side LOADMETER (= "outdoor coil" or environment source) - // + = from env: >0 during heating = coil heating - compressor electricity - rs_pSrcSideLoadMtr->S.qHtg += R.qhPrimary - R.ehPrimary; + for (int iM = 0; iM < 2; iM++) + { // accumulate values to LOADMETERs + // [0] accums both heating and cooling + // [1] accums heating + if (rs_pLoadMtr[ iM]) // primary = coil loads + rs_pLoadMtr[ iM]->S.qHtg += R.qhPrimary; + if (rs_pSrcSideLoadMtr[ iM]) // source-side (= "outdoor coil" or environment source) + // + = from env: >0 during heating = coil heating - compressor electricity + rs_pSrcSideLoadMtr[ iM]->S.qHtg += R.qhPrimary - R.ehPrimary; + } } else if (rs_mode == rsmCOOL) { @@ -3424,11 +3434,16 @@ RC RSYS::rs_EndSubhr() R.ecTot += R.ecPrimary + R.ecFan /* + R.ecParasitic, see above */; - if (rs_pLoadMtr) // primary LOADMTR (= indoor coil) - rs_pLoadMtr->S.qClg += R.qcSen + R.qcLat; - if (rs_pSrcSideLoadMtr) // source-side LOADMETER (= "outdoor coil" or environment source) - // + = from env: <0 when cooling = total cooling + compressor electricity - rs_pSrcSideLoadMtr->S.qClg += R.qcSen + R.qcLat - R.ecPrimary; + for (int iM = 0; iM < 3; iM += 2) + { // accumulate values to LOADMETERs + // [0] accums both heating and cooling + // [2] accums cooling + if (rs_pLoadMtr[iM]) // primary = coil loads + rs_pLoadMtr[iM]->S.qClg += R.qcSen + R.qcLat; + if (rs_pSrcSideLoadMtr[iM]) // source-side (= "outdoor coil" or environment source) + // + = from env: <0 when cooling = total cooling + compressor electricity + rs_pSrcSideLoadMtr[iM]->S.qClg += R.qcSen + R.qcLat - R.ecPrimary; + } } else if (rs_mode == rsmOAV) { // sensible "output" = fan power diff --git a/test/FanCoil.cse b/test/FanCoil.cse index 0f93ea782..dd0762156 100644 --- a/test/FanCoil.cse +++ b/test/FanCoil.cse @@ -913,6 +913,11 @@ LOADMETER MtrLoads LOADMETER MtrSSLoads +LOADMETER MtrHtgLoads + +LOADMETER MtrClgSSLoads + + IZXFER "Zone1-InfLU" izNVType = "AIRNETEXT" // Choice determining interzone ventilation @@ -2111,6 +2116,8 @@ RSYS "rsys1" rsFuelMtr = "MtrNatGas" // Natural gas use meter rsLoadMtr = "MtrLoads" rsSrcSideLoadMtr = "MtrSSLoads" + rsHtgLoadMtr = "MtrHtgLoads" + rsClgSrcSideLoadMtr = "MtrClgSSLoads" #if 1 @@ -2273,7 +2280,10 @@ TPERFCOLS( REPORTCOL,"","Yr",Y,.000001,3,MtrElec, MtrLoads, MtrSSLoads, 1, 1) REPORT ENUSEHR rpType=UDT rpFreq=HOUR rpTitle = "RSYS -- Fan Coil" rpDayBeg=Jan 1 rpDayEnd=Jan 3 TPERFCOLS( REPORTCOL,"Hr",$hour,H,.001,3,MtrElec, MtrLoads, MtrSSLoads, 1, 1) - +REPORT ENUSEMO2 rpType=UDT rpFreq=MONTH rpTitle = "RSYS -- Fan Coil htg/clg Meters" +TPERFCOLS( REPORTCOL,"Mon",@Top.monstr,M,.000001,3,MtrElec, MtrHtgLoads, MtrClgSSLoads, 1, 1) +REPORT rpType=UDT rpFreq=YEAR rpHeader = No +TPERFCOLS( REPORTCOL,"","Yr",Y,.000001,3,MtrElec, MtrHtgLoads, MtrClgSSLoads, 1, 1) #if 0 // columns for all DUCTSEGRES values (conduction, leakage / supply, return, total) diff --git a/test/ref/FANCOIL.REP b/test/ref/FANCOIL.REP index c132031d6..d1fb5b8b1 100644 --- a/test/ref/FANCOIL.REP +++ b/test/ref/FANCOIL.REP @@ -179,6 +179,27 @@ RSYS -- Fan Coil for Sat 03-Jan +RSYS -- Fan Coil htg/clg Meters + + Mon eHtg eHPBU eFanH eHTot qhZn qLMHtg qSSHtg eHTot2 qhZn2 eClg qcZone qLMClg qSSClg eClg2 qcZn2 ParErr + --- ------ ------ ------ ------ ------ ------ ------ ------ ------ ---------- ------ ------ ------ ------ ------ ------ + Jan 0 0 0.143 0.219 4.247 4.950 0 0.219 4.247 0 0 0 0 0 0 0 + Feb 0 0 0.0412 0.0753 1.214 1.427 0 0.0753 1.214 0.0328 -0.341 0 -0.379 0.0328 -0.341 -.0078 + Mar 0 0 .00305 0.0119 0.0904 0.105 0 0.0119 0.0904 0 0 0 0 0 0 -.0020 + Apr 0 0 .00618 0.0242 0.183 0.214 0 0.0242 0.183 0 0 0 0 0 0 -.0020 + May 0 0 0 0 0 0 0 0 0 0.0517 -0.824 0 -1.054 0.0517 -0.824 0 + Jun 0 0 0 0 0 0 0 0 0 0.168 -2.946 0 -3.755 0.168 -2.946 0 + Jul 0 0 0 0 0 0 0 0 0 0.236 -4.145 0 -5.276 0.236 -4.145 0 + Aug 0 0 0 0 0 0 0 0 0 0.241 -4.251 0 -5.371 0.241 -4.251 0 + Sep 0 0 0 0 0 0 0 0 0 0.115 -2.069 0 -2.548 0.115 -2.069 -.0001 + Oct 0 0 0 0 0 0 0 0 0 0.0364 -0.642 0 -0.778 0.0364 -0.642 -.0002 + Nov 0 0 0.0283 0.0434 0.834 0.979 0 0.0434 0.834 0.0207 0 0 0 0.0207 0 0 + Dec 0 0 0.137 0.197 4.049 4.727 0 0.197 4.049 0 0 0 0 0 0 -.0078 + + Yr 0 0 0.358 0.571 10.618 12.402 0 0.571 10.618 0.902 -15.22 0 -19.16 0.902 -15.22 .00781 + + + Duct / system / zone energy balance Mon Tzn ShCond ShLk ShTot QhSys QhZn QhBal ScCond ScLkS ScLkL ScTotS QcSys QcZn QcBal @@ -1740,7 +1761,7 @@ RSYS cooling subhour details for Wed 01-Jul ! Log for Run 001: -! CSE 0.908.0+wshp-autosize.c96fdcd9.298.dirty for Win32 console +! CSE 0.910.0+rsys-meters.4d72a370.188.dirty for Win32 console @@ -2661,6 +2682,11 @@ Input for Run 001: LOADMETER MtrSSLoads + LOADMETER MtrHtgLoads + + LOADMETER MtrClgSSLoads + + IZXFER "Zone1-InfLU" izNVType = "AIRNETEXT" // Choice determining interzone ventilation @@ -3859,6 +3885,8 @@ Input for Run 001: rsFuelMtr = "MtrNatGas" // Natural gas use meter rsLoadMtr = "MtrLoads" rsSrcSideLoadMtr = "MtrSSLoads" + rsHtgLoadMtr = "MtrHtgLoads" + rsClgSrcSideLoadMtr = "MtrClgSSLoads" # #if 1 @@ -4021,7 +4049,10 @@ Input for Run 001: REPORT ENUSEHR rpType=UDT rpFreq=HOUR rpTitle = "RSYS -- Fan Coil" rpDayBeg=Jan 1 rpDayEnd=Jan 3 TPERFCOLS( REPORTCOL,"Hr",$hour,H,.001,3,MtrElec, MtrLoads, MtrSSLoads, 1, 1) - + REPORT ENUSEMO2 rpType=UDT rpFreq=MONTH rpTitle = "RSYS -- Fan Coil htg/clg Meters" + TPERFCOLS( REPORTCOL,"Mon",@Top.monstr,M,.000001,3,MtrElec, MtrHtgLoads, MtrClgSSLoads, 1, 1) + REPORT rpType=UDT rpFreq=YEAR rpHeader = No + TPERFCOLS( REPORTCOL,"","Yr",Y,.000001,3,MtrElec, MtrHtgLoads, MtrClgSSLoads, 1, 1) # #if 0 0 // columns for all DUCTSEGRES values (conduction, leakage / supply, return, total) @@ -4263,18 +4294,18 @@ Input for Run 001: -! CSE 0.908.0+wshp-autosize.c96fdcd9.298.dirty for Win32 console run(s) done: Wed 27-Jul-22 5:21:36 pm +! CSE 0.910.0+rsys-meters.4d72a370.188.dirty for Win32 console run(s) done: Mon 28-Nov-22 2:32:34 pm ! Executable: d:\cse\msvc\cse.exe -! 27-Jul-22 4:17 pm (VS 14.29 3012608 bytes) (HPWH 1.18.1) +! 28-Nov-22 2:02 pm (VS 14.29 2625536 bytes) (HPWH 1.19.0) ! Command line: -x! -t1 fancoil ! Input file: D:\cse\test\fancoil.cse ! Report file: D:\cse\test\fancoil.rep ! Timing info -- -! Input: Time = 0.06 Calls = 1 T/C = 0.0570 +! Input: Time = 0.07 Calls = 1 T/C = 0.0700 ! AutoSizing: Time = 0.00 Calls = 0 T/C = 0.0000 -! Simulation: Time = 3.15 Calls = 1 T/C = 3.1510 +! Simulation: Time = 3.56 Calls = 1 T/C = 3.5600 ! Reports: Time = 0.00 Calls = 1 T/C = 0.0040 -! Total: Time = 3.22 Calls = 1 T/C = 3.2170 +! Total: Time = 3.64 Calls = 1 T/C = 3.6370