LCOV - code coverage report
Current view: top level - EnergyPlus/PhaseChangeModeling - HysteresisModel.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 112 210 53.3 %
Date: 2023-01-17 19:17:23 Functions: 9 9 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : #include <ObjexxFCL/Array1D.hh>
      49             : 
      50             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      51             : #include <EnergyPlus/DataHeatBalance.hh>
      52             : #include <EnergyPlus/DataIPShortCuts.hh>
      53             : #include <EnergyPlus/EnergyPlus.hh>
      54             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      55             : #include <EnergyPlus/PhaseChangeModeling/HysteresisModel.hh>
      56             : #include <EnergyPlus/UtilityRoutines.hh>
      57             : 
      58             : namespace EnergyPlus {
      59             : 
      60             : namespace HysteresisPhaseChange {
      61             : 
      62       13521 :     HysteresisPhaseChange *HysteresisPhaseChange::factory(EnergyPlusData &state, const std::string &objectName)
      63             :     {
      64       13521 :         if (state.dataHysteresisPhaseChange->getHysteresisModels) {
      65         741 :             readAllHysteresisModels(state);
      66         741 :             state.dataHysteresisPhaseChange->getHysteresisModels = false;
      67             :         }
      68       13523 :         for (auto &hm : state.dataHysteresisPhaseChange->hysteresisPhaseChangeModels) {
      69           3 :             if (hm.name == objectName) {
      70           1 :                 return &hm;
      71             :             }
      72             :         }
      73             :         // because of the passive linking between materials and material property objects,
      74             :         // we don't know ahead of time for sure whether we will have a material property
      75             :         // so we can't return fatal here if it isn't found, just leave it null
      76       13520 :         return nullptr;
      77             :     }
      78             : 
      79     1099750 :     Real64 HysteresisPhaseChange::getEnthalpy(Real64 T, Real64 Tc, Real64 tau1, Real64 tau2)
      80             :     {
      81             :         // Looks up the enthalpy on the characteristic curve defined by the parameters Tc, tau1, and tau2,
      82             :         // and the position on that curve defined by T.
      83     1099750 :         Real64 eta1 = (this->totalLatentHeat / 2) * exp(-2 * std::abs(T - Tc) / tau1);
      84     1099750 :         Real64 eta2 = (this->totalLatentHeat / 2) * exp(-2 * std::abs(T - Tc) / tau2);
      85     1099750 :         if (T <= Tc) {
      86      899846 :             return (this->specificHeatSolid * T) + eta1;
      87             :         } else {
      88      199904 :             return (this->specificHeatSolid * Tc) + this->totalLatentHeat + this->specificHeatLiquid * (T - Tc) - eta2;
      89             :         }
      90             :     }
      91             : 
      92      549875 :     Real64 HysteresisPhaseChange::getCurrentSpecificHeat(
      93             :         Real64 prevTempTD, Real64 updatedTempTDT, Real64 phaseChangeTempReverse, int prevPhaseChangeState, int &phaseChangeState)
      94             :     {
      95             :         // Main public facing function; returns the current specific heat based on input properties, and current and previous conditions.
      96             :         // In a future version, this could be compartmentalized to track all states and histories, but it would require some further modification to
      97             :         // the HBFDManager
      98      549875 :         Real64 TempLowPCM = this->peakTempMelting - this->deltaTempMeltingLow;
      99      549875 :         Real64 TempHighPCM = this->peakTempMelting + this->deltaTempMeltingHigh;
     100             :         Real64 Tc;   // assigned later
     101             :         Real64 Tau1; // assigned later
     102             :         Real64 Tau2; // assigned later
     103      549875 :         Real64 TempLowPCF = this->peakTempFreezing - this->deltaTempFreezingLow;
     104      549875 :         Real64 TempHighPCF = this->peakTempFreezing + this->deltaTempFreezingHigh;
     105             :         Real64 Cp;
     106      549875 :         Real64 phaseChangeDeltaT = prevTempTD - updatedTempTDT;
     107             : 
     108             :         // determine phase change state and curve characteristics based on delta T direction, updated temp, and previous state
     109      549875 :         if (phaseChangeDeltaT <= 0) {
     110      169781 :             Tc = this->peakTempMelting;
     111      169781 :             Tau1 = this->deltaTempMeltingLow;
     112      169781 :             Tau2 = this->deltaTempMeltingHigh;
     113      169781 :             if (updatedTempTDT < TempLowPCM) {
     114       55441 :                 phaseChangeState = PhaseChangeStates::CRYSTALLIZED;
     115      114340 :             } else if (updatedTempTDT >= TempLowPCM && updatedTempTDT <= TempHighPCM) {
     116      114340 :                 phaseChangeState = PhaseChangeStates::MELTING;
     117      228680 :                 if (prevPhaseChangeState == PhaseChangeStates::FREEZING || prevPhaseChangeState == PhaseChangeStates::TRANSITION) {
     118        4271 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     119             :                 }
     120           0 :             } else if (updatedTempTDT > TempHighPCM) {
     121           0 :                 phaseChangeState = PhaseChangeStates::LIQUID;
     122             :             }
     123             :         } else { // phaseChangeDeltaT > 0
     124      380094 :             Tc = this->peakTempFreezing;
     125      380094 :             Tau1 = this->deltaTempFreezingLow;
     126      380094 :             Tau2 = this->deltaTempFreezingHigh;
     127      380094 :             if (updatedTempTDT < TempLowPCF) {
     128      286009 :                 phaseChangeState = PhaseChangeStates::CRYSTALLIZED;
     129       94085 :             } else if (updatedTempTDT >= TempLowPCF && updatedTempTDT <= TempHighPCF) {
     130       14416 :                 phaseChangeState = PhaseChangeStates::FREEZING;
     131       28832 :                 if (prevPhaseChangeState == PhaseChangeStates::MELTING || prevPhaseChangeState == PhaseChangeStates::TRANSITION) {
     132           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     133             :                 }
     134       79669 :             } else if (updatedTempTDT > TempHighPCF) {
     135       79669 :                 phaseChangeState = PhaseChangeStates::LIQUID;
     136             :             }
     137             :         }
     138             : 
     139             :         // determine if we are transitioning or not
     140      549875 :         if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::CRYSTALLIZED) {
     141           0 :             this->phaseChangeTransition = true;
     142      549875 :         } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::FREEZING) {
     143           0 :             this->phaseChangeTransition = true;
     144             :             // this->phaseChangeState = 0; ?????
     145      549875 :         } else if (prevPhaseChangeState == PhaseChangeStates::FREEZING && phaseChangeState == PhaseChangeStates::TRANSITION) {
     146           0 :             this->phaseChangeTransition = true;
     147      549875 :         } else if (prevPhaseChangeState == PhaseChangeStates::CRYSTALLIZED && phaseChangeState == PhaseChangeStates::TRANSITION) {
     148           0 :             this->phaseChangeTransition = true;
     149             :         } else {
     150      549875 :             this->phaseChangeTransition = false;
     151             :         }
     152             : 
     153             :         // now calculate the enthalpy appropriately
     154      549875 :         if (!this->phaseChangeTransition) {
     155      549875 :             this->enthOld = this->getEnthalpy(prevTempTD, Tc, Tau1, Tau2);
     156      549875 :             this->enthNew = this->getEnthalpy(updatedTempTDT, Tc, Tau1, Tau2);
     157             :         } else {
     158           0 :             if (prevPhaseChangeState == PhaseChangeStates::FREEZING && phaseChangeState == PhaseChangeStates::TRANSITION) {
     159           0 :                 this->enthRev =
     160           0 :                     this->getEnthalpy(phaseChangeTempReverse, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     161           0 :                 this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
     162           0 :                 this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     163           0 :                 this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     164           0 :                 if (this->enthNew < this->enthRev && this->enthNew >= this->enthalpyF && updatedTempTDT <= prevTempTD) {
     165           0 :                     phaseChangeState = PhaseChangeStates::FREEZING;
     166           0 :                     this->enthNew =
     167           0 :                         this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     168           0 :                 } else if (this->enthNew < this->enthalpyF && this->enthNew > this->enthalpyM) {
     169           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     170           0 :                     this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
     171           0 :                 } else if (this->enthNew < this->enthalpyF && updatedTempTDT > phaseChangeTempReverse) {
     172           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     173           0 :                     this->enthNew =
     174           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     175           0 :                 } else if (this->enthNew <= this->enthalpyM && updatedTempTDT <= phaseChangeTempReverse) {
     176           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     177           0 :                     this->enthNew =
     178           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     179             :                 }
     180           0 :             } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::TRANSITION) {
     181           0 :                 if (updatedTempTDT < phaseChangeTempReverse) {
     182           0 :                     Tc = this->peakTempMelting;
     183           0 :                     Tau1 = this->deltaTempMeltingLow;
     184           0 :                     Tau2 = this->deltaTempMeltingHigh;
     185           0 :                 } else if (updatedTempTDT > phaseChangeTempReverse) {
     186           0 :                     Tc = this->peakTempFreezing;
     187           0 :                     Tau1 = this->deltaTempFreezingLow;
     188           0 :                     Tau2 = this->deltaTempFreezingHigh;
     189             :                 }
     190           0 :                 this->enthRev = this->getEnthalpy(phaseChangeTempReverse, Tc, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     191           0 :                 this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
     192           0 :                 this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     193           0 :                 this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     194           0 :                 if (updatedTempTDT < phaseChangeTempReverse && this->enthNew > this->enthalpyF) {
     195           0 :                     phaseChangeState = PhaseChangeStates::FREEZING;
     196           0 :                     this->enthNew =
     197           0 :                         this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     198           0 :                 } else if (this->enthNew < this->enthalpyF && this->enthNew > this->enthalpyM &&
     199           0 :                            (updatedTempTDT < prevTempTD || updatedTempTDT > prevTempTD)) {
     200           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     201           0 :                     this->enthNew =
     202           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     203           0 :                 } else if (this->enthNew <= this->enthalpyM && updatedTempTDT >= prevTempTD && this->enthNew > this->enthOld) {
     204           0 :                     phaseChangeState = PhaseChangeStates::MELTING;
     205           0 :                     this->enthNew =
     206           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     207             :                 }
     208           0 :             } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::CRYSTALLIZED) {
     209           0 :                 this->enthRev =
     210           0 :                     this->getEnthalpy(phaseChangeTempReverse, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     211           0 :                 this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     212           0 :                 this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     213           0 :                 this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     214           0 :                 if (this->enthNew < this->enthalpyF && this->enthNew > this->enthalpyM) {
     215           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     216           0 :                     this->enthNew =
     217           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     218           0 :                 } else if (this->enthNew <= this->enthalpyM && updatedTempTDT >= prevTempTD) {
     219           0 :                     phaseChangeState = PhaseChangeStates::MELTING;
     220           0 :                     this->enthNew = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     221             :                 }
     222           0 :             } else if (prevPhaseChangeState == PhaseChangeStates::MELTING && phaseChangeState == PhaseChangeStates::TRANSITION) {
     223           0 :                 this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
     224           0 :                 this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     225           0 :                 this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     226           0 :                 if (this->enthNew < this->enthOld && updatedTempTDT < prevTempTD) {
     227           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     228           0 :                     this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthOld - (this->specHeatTransition * prevTempTD));
     229           0 :                 } else if (this->enthNew < this->enthalpyF && this->enthNew > this->enthalpyM && updatedTempTDT < prevTempTD) {
     230           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     231           0 :                     this->enthNew =
     232           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     233           0 :                 } else if (this->enthNew >= this->enthalpyF && updatedTempTDT <= phaseChangeTempReverse) {
     234           0 :                     phaseChangeState = PhaseChangeStates::TRANSITION;
     235           0 :                     this->enthNew =
     236           0 :                         (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     237             :                 }
     238           0 :             } else if (prevPhaseChangeState == PhaseChangeStates::TRANSITION && phaseChangeState == PhaseChangeStates::FREEZING) {
     239           0 :                 this->enthalpyM = this->getEnthalpy(updatedTempTDT, this->peakTempMelting, this->deltaTempMeltingLow, this->deltaTempMeltingHigh);
     240           0 :                 this->enthalpyF = this->getEnthalpy(updatedTempTDT, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     241           0 :                 this->enthRev =
     242           0 :                     this->getEnthalpy(phaseChangeTempReverse, this->peakTempFreezing, this->deltaTempFreezingLow, this->deltaTempFreezingHigh);
     243           0 :                 this->enthNew = (this->specHeatTransition * updatedTempTDT) + (this->enthRev - (this->specHeatTransition * phaseChangeTempReverse));
     244             :             }
     245             :         }
     246             : 
     247             :         // then calculate the specific heat and return it
     248      549875 :         if (!this->phaseChangeTransition) {
     249      549875 :             if (this->enthNew == this->enthOld) {
     250       74919 :                 Cp = this->CpOld;
     251             :             } else {
     252      474956 :                 Cp = this->specHeat(prevTempTD, updatedTempTDT, Tc, Tau1, Tau2, this->enthOld, this->enthNew);
     253             :             }
     254             :         } else {
     255           0 :             Cp = this->specHeatTransition;
     256             :         }
     257      549875 :         this->CpOld = Cp;
     258      549875 :         return Cp;
     259             :     }
     260             : 
     261      474956 :     Real64 HysteresisPhaseChange::specHeat(Real64 temperaturePrev,
     262             :                                            Real64 temperatureCurrent,
     263             :                                            Real64 criticalTemperature,
     264             :                                            Real64 tau1,
     265             :                                            Real64 tau2,
     266             :                                            Real64 EnthalpyOld,
     267             :                                            Real64 EnthalpyNew)
     268             :     {
     269             : 
     270             :         //    Tc                  ! Critical (Melting/Freezing) Temperature of PCM
     271             :         //    Tau1                ! Width of Melting Zone low
     272             :         //    Tau2                ! Width of Melting Zone high
     273             :         //    EnthalpyOld         ! Previous Timestep Nodal Enthalpy
     274             :         //    EnthalpyNew         ! Current Timestep Nodal Enthalpy
     275             : 
     276      474956 :         Real64 T = temperatureCurrent;
     277             : 
     278      474956 :         if (T < criticalTemperature) {
     279      376100 :             Real64 DEta1 = -(this->totalLatentHeat * (T - criticalTemperature) * exp(-2 * std::abs(T - criticalTemperature) / tau1)) /
     280      376100 :                            (tau1 * std::abs(T - criticalTemperature));
     281      376100 :             Real64 Cp1 = this->specificHeatSolid;
     282      376100 :             return (Cp1 + DEta1);
     283       98856 :         } else if (T == criticalTemperature) {
     284           0 :             return (EnthalpyNew - EnthalpyOld) / (temperatureCurrent - temperaturePrev);
     285       98856 :         } else if (T > criticalTemperature) {
     286       98856 :             Real64 DEta2 = (this->totalLatentHeat * (T - criticalTemperature) * exp(-2 * std::abs(T - criticalTemperature) / tau2)) /
     287       98856 :                            (tau2 * std::abs(T - criticalTemperature));
     288       98856 :             Real64 Cp2 = this->specificHeatLiquid;
     289       98856 :             return Cp2 + DEta2;
     290             :         } else {
     291           0 :             return 0;
     292             :         }
     293             :     }
     294             : 
     295     1209725 :     Real64 HysteresisPhaseChange::getConductivity(Real64 T)
     296             :     {
     297     1209725 :         if (T < this->peakTempMelting) {
     298     1154772 :             return this->fullySolidThermalConductivity;
     299       54953 :         } else if (T > this->peakTempFreezing) {
     300       54953 :             return this->fullyLiquidThermalConductivity;
     301             :         } else {
     302           0 :             return (this->fullySolidThermalConductivity + this->fullyLiquidThermalConductivity) / 2.0;
     303             :         }
     304             :     }
     305             : 
     306      549875 :     Real64 HysteresisPhaseChange::getDensity(Real64 T)
     307             :     {
     308      549875 :         if (T < this->peakTempMelting) {
     309      520447 :             return this->fullySolidDensity;
     310       29428 :         } else if (T > this->peakTempFreezing) {
     311       29428 :             return this->fullyLiquidDensity;
     312             :         } else {
     313           0 :             return (this->fullySolidDensity + this->fullyLiquidDensity) / 2.0;
     314             :         }
     315             :     }
     316             : 
     317         741 :     void readAllHysteresisModels(EnergyPlusData &state)
     318             :     {
     319             : 
     320             :         // convenience variables
     321         741 :         state.dataIPShortCut->cCurrentModuleObject = "MaterialProperty:PhaseChangeHysteresis";
     322         741 :         state.dataHysteresisPhaseChange->numHysteresisModels =
     323         741 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
     324             : 
     325             :         // loop over all hysteresis input instances, if zero, this will simply not do anything
     326         742 :         for (int hmNum = 1; hmNum <= state.dataHysteresisPhaseChange->numHysteresisModels; ++hmNum) {
     327             : 
     328             :             // just a few vars to pass in and out to GetObjectItem
     329             :             int ioStatus;
     330             :             int numAlphas;
     331             :             int numNumbers;
     332             : 
     333             :             // get the input data and store it in the Shortcuts structures
     334           8 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     335           1 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
     336             :                                                                      hmNum,
     337           1 :                                                                      state.dataIPShortCut->cAlphaArgs,
     338             :                                                                      numAlphas,
     339           1 :                                                                      state.dataIPShortCut->rNumericArgs,
     340             :                                                                      numNumbers,
     341             :                                                                      ioStatus,
     342           1 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
     343           1 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     344           1 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     345           1 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     346             : 
     347             :             // the input processor validates the numeric inputs based on the IDD definition
     348             :             // still validate the name to make sure there aren't any duplicates or blanks
     349             :             // blanks are easy: fatal if blank
     350           1 :             if (state.dataIPShortCut->lAlphaFieldBlanks[0]) {
     351           0 :                 ShowFatalError(state, "Invalid input for " + state.dataIPShortCut->cCurrentModuleObject + " object: Name cannot be blank");
     352             :             }
     353             : 
     354             :             // we just need to loop over the existing vector elements to check for duplicates since we haven't add this one yet
     355           1 :             for (auto &existingHysteresisModel : state.dataHysteresisPhaseChange->hysteresisPhaseChangeModels) {
     356           0 :                 if (state.dataIPShortCut->cAlphaArgs(1) == existingHysteresisModel.name) {
     357           0 :                     ShowFatalError(state,
     358           0 :                                    "Invalid input for " + state.dataIPShortCut->cCurrentModuleObject +
     359           0 :                                        " object: Duplicate name found: " + existingHysteresisModel.name);
     360             :                 }
     361             :             }
     362             : 
     363             :             // now build out a new hysteresis instance and add it to the vector
     364           2 :             HysteresisPhaseChange thisHM;
     365           1 :             thisHM.name = state.dataIPShortCut->cAlphaArgs(1);
     366           1 :             thisHM.totalLatentHeat = state.dataIPShortCut->rNumericArgs(1);
     367           1 :             thisHM.fullyLiquidThermalConductivity = state.dataIPShortCut->rNumericArgs(2);
     368           1 :             thisHM.fullyLiquidDensity = state.dataIPShortCut->rNumericArgs(3);
     369           1 :             thisHM.specificHeatLiquid = state.dataIPShortCut->rNumericArgs(4);
     370           1 :             thisHM.deltaTempMeltingHigh = state.dataIPShortCut->rNumericArgs(5);
     371           1 :             thisHM.peakTempMelting = state.dataIPShortCut->rNumericArgs(6);
     372           1 :             thisHM.deltaTempMeltingLow = state.dataIPShortCut->rNumericArgs(7);
     373           1 :             thisHM.fullySolidThermalConductivity = state.dataIPShortCut->rNumericArgs(8);
     374           1 :             thisHM.fullySolidDensity = state.dataIPShortCut->rNumericArgs(9);
     375           1 :             thisHM.specificHeatSolid = state.dataIPShortCut->rNumericArgs(10);
     376           1 :             thisHM.deltaTempFreezingHigh = state.dataIPShortCut->rNumericArgs(11);
     377           1 :             thisHM.peakTempFreezing = state.dataIPShortCut->rNumericArgs(12);
     378           1 :             thisHM.deltaTempFreezingLow = state.dataIPShortCut->rNumericArgs(13);
     379           1 :             thisHM.specHeatTransition = (thisHM.specificHeatSolid + thisHM.specificHeatLiquid) / 2.0;
     380           1 :             thisHM.CpOld = thisHM.specificHeatSolid;
     381           1 :             state.dataHysteresisPhaseChange->hysteresisPhaseChangeModels.push_back(thisHM);
     382             :         }
     383         741 :     }
     384             : 
     385             : } // namespace HysteresisPhaseChange
     386             : 
     387        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13