diff --git a/.gitattributes b/.gitattributes index 605ab25eef..ef7fd0c800 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,7 @@ # Explicitly declare text files we want to always be normalized and converted # to native line endings on checkout. *.mo text +*.mos text *.mop text *.py text *.txt text diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/EN12975HeatLoss_QuasiDynamic.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/EN12975HeatLoss_QuasiDynamic.mo deleted file mode 100644 index fdebf069e5..0000000000 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/EN12975HeatLoss_QuasiDynamic.mo +++ /dev/null @@ -1,67 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.BaseClasses; -model EN12975HeatLoss_QuasiDynamic - "Model to calculate the quasi-dynamic heat loss of a pvt/solar collector following the ISO 9806:2013 quasi-dynamic method" - extends Modelica.Blocks.Icons.Block; - - replaceable package Medium = Modelica.Media.Interfaces.PartialMedium - "Medium in the system"; - parameter Integer nSeg = 3 "Number of segments"; - - parameter Real c1(final unit="W/(m2.K)", final min=0) - "Linear heat loss coefficient"; - parameter Real c2(final unit="W/(m2.K2)", final min=0) - "Quadratic heat loss coefficient"; - parameter Real c3(final unit="J/(m3.K)", final min=0) - "Windspeed dependence of heat losses"; - parameter Real c4(final unit="", final min=0) - "Sky temperature dependence of the heat-loss coefficient"; - parameter Real c6(final unit="s/m", final min=0) - "Windspeed dependence of zero-loss efficiency"; - parameter Real A_c(final unit="m2", final min=0) - "Collector gross area"; - - Modelica.Blocks.Interfaces.RealOutput QLos_flow[nSeg] - "Limited heat loss rate at current conditions" - annotation (Placement(transformation(extent={{100,-10},{120,10}}))); - - Modelica.Blocks.Interfaces.RealInput G - "Global solar irradiance [W/m2]" - annotation (Placement(transformation(extent={{-140,-34},{-100,6}}))); - - Modelica.Blocks.Interfaces.RealInput TFlu[nSeg] - "Temperature of the heat transfer fluid [K]" - annotation (Placement(transformation(extent={{-140,-64},{-100,-24}}))); - - Modelica.Blocks.Interfaces.RealInput windSpePlane - "Wind speed normal to collector plane (m/s)" - annotation (Placement(transformation(extent={{-140,-92},{-100,-52}}))); - - IDEAS.BoundaryConditions.WeatherData.Bus WeaBus - "Bus with weather data" - annotation (Placement(transformation(extent={{-114,62},{-94,82}}))); - - IDEAS.Fluid.PvtCollectors.BaseClasses.PartialEN12975HeatLoss_QuasiDynamic partialLoss( - redeclare package Medium = IDEAS.Media.Water, - nSeg=nSeg, - c1=c1, - c2=c2, - c3=c3, - c4=c4, - c6=c6, - A_c=A_c) annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); - -equation - connect(TFlu, partialLoss.TFlu); - connect(G, partialLoss.G); - connect(partialLoss.TEnv, WeaBus.TDryBul); - connect(partialLoss.E_L, WeaBus.HHorIR); - connect(partialLoss.u, windSpePlane); - connect(partialLoss.QLos_flow, QLos_flow); - - annotation ( - Icon(coordinateSystem(preserveAspectRatio=false)), - Diagram(coordinateSystem(preserveAspectRatio=false)), - Documentation(info=" -

Model to calculate the quasi-dynamic heat loss of a pvt/solar collector following the ISO 9806:2013 quasi-dynamic method.

-")); -end EN12975HeatLoss_QuasiDynamic; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/EN12975HeatLoss_SteadyState.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/EN12975HeatLoss_SteadyState.mo deleted file mode 100644 index ff36bd8ce4..0000000000 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/EN12975HeatLoss_SteadyState.mo +++ /dev/null @@ -1,89 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.BaseClasses; -block EN12975HeatLoss_SteadyState - "Calculate the steady-state heat loss of a solar collector per EN12975" - extends IDEAS.Fluid.SolarCollectors.BaseClasses.PartialHeatLoss( - QLos_internal = A_c/nSeg * {dT[i] * (c1 - c2 * dT[i]) for i in 1:nSeg}); - - parameter Modelica.Units.SI.CoefficientOfHeatTransfer c1(final min=0) - "c2 from ratings data"; - - parameter Real c2(final unit = "W/(m2.K2)", final min=0) - "c2 from ratings data"; - -annotation ( -defaultComponentName="heaLos", -Documentation(info=" -

-This component computes the heat loss from the solar thermal collector -to the environment. It is designed anticipating ratings data collected in -accordance with EN12975. A negative heat loss indicates that heat -is being lost to the environment. -

-

-This model calculates the heat loss to the ambient, for each -segment i ∈ {1, ..., nseg} -where nseg is the number of segments, as -

-

-Qlos,i = Ac ⁄ nseg -(Tenv-Tflu,i) (a1 - a2 - (Tenv-Tflu,i)) -

-

-where -a1 > 0 is the heat loss coefficient -from EN12975 ratings data, -a2 ≥ 0 is the temperature dependence of heat loss -from EN12975 ratings data, -Ac is the collector area, -Tenv is the environment temperature and -Tflu,i is the fluid temperature in segment -i ∈ {1, ..., nseg}. -

-

-This model reduces the heat loss rate to 0 when the fluid temperature is within -1 Kelvin of the minimum temperature of the medium model. The calculation is -performed using the - -IDEAS.Utilities.Math.Functions.smoothHeaviside function. -

-

Implementation

-

-EN 12975 uses the arithmetic average temperature of the collector fluid inlet -and outlet temperature to compute the heat loss (see Duffie and Beckmann, p. 293). -However, unless the environment temperature that was present during the collector rating -is known, which is not the case, one cannot compute -a log mean temperature difference that would improve the UA calculation. Hence, -this model is using the fluid temperature of each segment -to compute the heat loss to the environment. -If the arithmetic average temperature were used, then segments at the collector -outlet could be cooled below the ambient temperature, which violates the 2nd law -of Thermodynamics. -

- -

References

-

-CEN 2006, European Standard 12975-1:2006, European Committee for Standardization -

-", revisions=" - -")); -end EN12975HeatLoss_SteadyState; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/ElectricalPVT.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/ElectricalPVT.mo new file mode 100644 index 0000000000..04fa035031 --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/ElectricalPVT.mo @@ -0,0 +1,216 @@ +within IDEAS.Fluid.PVTCollectors.BaseClasses; +model ElectricalPVT "Visible block to compute electrical power output using PVWatts v5 approach" + extends Modelica.Blocks.Icons.Block; + extends SolarCollectors.BaseClasses.PartialParameters; + // Parameters + parameter Integer nSeg = 1 "Number of segments"; + parameter Modelica.Units.SI.Irradiance HGloHorNom = 1000 "Nominal global irradiance"; + parameter Modelica.Units.SI.Efficiency pLossFactor = 0.10 "PV loss factor"; + parameter Modelica.Units.SI.Temperature TpvtRef = 298.15 "Reference cell temperature [K]"; + parameter Real gamma "Temperature coefficient [1/K]"; + parameter Real P_nominal "Nominal PV power [W]"; + parameter Real A "PV area [m2]"; + parameter Real eta0 "Zero-loss efficiency"; + parameter Real tauAlphaEff "Effective transmittance–absorptance product"; + parameter Real c1 "First-order heat loss coefficient"; + parameter Real etaEl "Electrical efficiency"; + + final parameter Modelica.Units.SI.CoefficientOfHeatTransfer UAbsFluid = + ((tauAlphaEff - etaEl) * (c1 + abs(gamma)*HGloHorNom)) + / ((tauAlphaEff - etaEl) - eta0) + "Heat transfer coefficient between the fluid and the PV cells, calculated from datasheet parameters"; + + // Inputs + Modelica.Blocks.Interfaces.RealInput Tm[nSeg] + "Fluid temperatures per segment [K]" + annotation (Placement(transformation(extent={{-140,40},{-100,80}}), + iconTransformation(extent={{-140,40},{-100,80}}))); + Modelica.Blocks.Interfaces.RealInput qth[nSeg] + "Thermal power density per segment [W/m2]" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}), + iconTransformation(extent={{-140,-20},{-100,20}}))); + Modelica.Blocks.Interfaces.RealInput HGloTil + "Global tilted irradiance [W/m2]" + annotation (Placement(transformation(extent={{-140,-80},{-100,-40}}), + iconTransformation(extent={{-140,-80},{-100,-40}}))); + + // Outputs + Modelica.Blocks.Interfaces.RealOutput pEl + "Total electrical power output [W/m2]" + annotation (Placement(transformation(extent={{100,40},{140,80}}), + iconTransformation(extent={{100,40},{140,80}}))); + Modelica.Blocks.Interfaces.RealOutput temMod + "Average cell temperature [K]" + annotation (Placement(transformation(extent={{100,-20},{140,20}}), + iconTransformation(extent={{100,-20},{140,20}}))); + Modelica.Blocks.Interfaces.RealOutput temMea + "Average fluid temperature [K]" + annotation (Placement(transformation(extent={{100,-80},{140,-40}}), + iconTransformation(extent={{100,-80},{140,-40}}))); + +protected + Real temCell[nSeg]; + Real temDiff[nSeg]; + Real solarPowerInternal[nSeg]; + +equation + for i in 1:nSeg loop + temCell[i] = Tm[i] + qth[i] / UAbsFluid; + temDiff[i] = temCell[i] - TpvtRef; + solarPowerInternal[i] = (A_c/nSeg) * (P_nominal/A) * (HGloTil/HGloHorNom) * + (1 + gamma * temDiff[i]) * (1 - pLossFactor); + end for; + + pEl = sum(solarPowerInternal); + temMod = sum(temCell)/nSeg; + temMea = sum(Tm)/nSeg; + +annotation ( + defaultComponentName="eleGen", + Documentation(info=" +

+This component computes the electrical power output of a photovoltaic-thermal (PVT) collector using the PVWatts v5 methodology (Dobos, 2014), adapted for PVT systems. It is part of a validated, open-source Modelica implementation that relies solely on manufacturer datasheet parameters, as described in Meertens et al. (2025). +

+ +

+The model calculates the electrical output for each segment i ∈ {1, ..., nseg} as: +

+ +

+Pel,i = (Ac / nseg) · (Pnom / A) · (Gtilt / Gnom) · (1 + γ · ΔTi) · (1 - pLossFactor) +

+ +

+where: +

+

+

+The PV cell temperature is estimated from the fluid temperature and thermal power density using: +

+

+Tcell,i = Tm,i + qth,i / UAbsFluid +

+

+ The internal heat transfer coefficient UAbsFluid is approximately calculated from datasheet parameters: +

+
+
UAbsFluid =
+ + + + + + + +
+ (τ·α)eff – η0,el · (c1 + c3·u + b1,el) +
+ (τ·α)eff – η0,el + – (1 – c60,th·u) · η0,th +
+
+ +
Electrical performance and losses
+

+The electrical submodel includes an overall system loss factor pLossFactor. NREL’s PVWatts reports a total electrical power loss of 14%, resulting from the following mechanisms: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Electrical power loss mechanismDefault value
Soiling2 %
Shading3 %
Mismatch2 %
Wiring2 %
Connections0.5 %
Light‑induced degradation1.5 %
Nameplate rating1 %
Availability3 %
Total14 %
+

+ For well-maintained, unshaded modules, experimental validation (Meertens et al., 2025) +found that using pLossFactor = 9 % gives excellent agreement with +measured electrical output. For PVT collectors with high positive tolerance on the +electrical output, this system loss factor can even be reduced more. +Users may adjust pLossFactor to account for site-specific soiling or shading effects. +

+

Implementation Notes

+

+This model is designed for (unglazed) PVT collectors and supports discretization into multiple segments to capture temperature gradients along the flow path. It is compatible with the thermal +model based on ISO 9806:2013 and is suitable for dynamic simulations where irradiance and fluid temperatures vary over time. +

+ +

References

+ +", +revisions=" + +")); + +end ElectricalPVT; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/EN12975HeatLoss_QD.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/EN12975HeatLoss_QD.mo deleted file mode 100644 index 8c63fcb508..0000000000 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/EN12975HeatLoss_QD.mo +++ /dev/null @@ -1,79 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.BaseClasses.Examples; -model EN12975HeatLoss_QD "Example showing the use of EN12975HeatLoss_QuasiDynamic" - extends Modelica.Icons.Example; - parameter IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic per= - IDEAS.Fluid.PvtCollectors.Data.Uncovered.UI_TRNSYSValidation() - "Performance data" annotation (choicesAllMatching=true); - Modelica.Blocks.Sources.Sine T1( - amplitude=15, - f=0.1, - offset=273.15 + 10) "Temperature of the first segment" - annotation (Placement(transformation(extent={{30,-90},{50,-70}}))); - Modelica.Blocks.Sources.Sine T2( - f=0.1, - amplitude=15, - offset=273.15 + 15) "Temperature of the second segment" - annotation (Placement(transformation(extent={{-10,-70},{10,-50}}))); - Modelica.Blocks.Sources.Sine T3( - f=0.1, - amplitude=15, - offset=273.15 + 20) "Temperature of the third segment" - annotation (Placement(transformation(extent={{-50,-50},{-30,-30}}))); - BaseClasses.EN12975HeatLoss_QuasiDynamic eN12975HeatLoss_QuasiDynamic( - nSeg=3, - redeclare package Medium = IDEAS.Media.Water, - a1=per.a1, - a2=per.a2, - c3=per.c3, - c4=per.c4, - c6=per.c6, - A_c=per.A) annotation (Placement(transformation(extent={{74,12},{94,32}}))); - BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam= - Modelica.Utilities.Files.loadResource("modelica://IDEAS/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos")) - "Weather data input file" - annotation (Placement(transformation(extent={{-84,70},{-64,90}}))); - Modelica.Blocks.Sources.RealExpression globIrrTil(y=600) "[W/m2]" - annotation (Placement(transformation(extent={{-47.5,26},{-28.5,42}}))); -equation - connect(weaDat.weaBus, eN12975HeatLoss_QuasiDynamic.WeaBus) annotation (Line( - points={{-64,80},{68,80},{68,29.2},{73.6,29.2}}, - color={255,204,51}, - thickness=0.5)); - connect(eN12975HeatLoss_QuasiDynamic.G, globIrrTil.y) annotation (Line(points={{72,20.6}, - {-24,20.6},{-24,34},{-27.55,34}}, color={0,0,127})); - connect(T3.y, eN12975HeatLoss_QuasiDynamic.TFlu[1]) annotation (Line(points={{-29,-40}, - {62,-40},{62,16.9333},{72,16.9333}}, color={0, - 0,127})); - connect(T2.y, eN12975HeatLoss_QuasiDynamic.TFlu[2]) annotation (Line(points={{11,-60}, - {62,-60},{62,17.6},{72,17.6}}, - color={0,0,127})); - connect(T1.y, eN12975HeatLoss_QuasiDynamic.TFlu[3]) annotation (Line(points={{51,-80}, - {62,-80},{62,18.2667},{72,18.2667}}, - color={0,0,127})); - annotation ( - Documentation(info=" -

-This examples demonstrates the implementation of - -IDEAS.Fluid.SolarCollectors.BaseClasses.EN12975HeatLoss. -

-", -revisions=" - - "), - __Dymola_Commands(file= - "modelica://IDEAS/Resources/Scripts/Dymola/Fluid/SolarCollectors/BaseClasses/Examples/EN12975HeatLoss.mos" - "Simulate and plot"), - experiment(Tolerance=1e-6, StopTime=100)); -end EN12975HeatLoss_QD; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/ISO9806HeatLoss.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/ISO9806HeatLoss.mo new file mode 100644 index 0000000000..6a92ff5e3a --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/ISO9806HeatLoss.mo @@ -0,0 +1,122 @@ +within IDEAS.Fluid.PVTCollectors.BaseClasses.Examples; +model ISO9806HeatLoss + "Example showing the use of ISO9806QuasiDynamicHeatLoss" + extends Modelica.Icons.Example; + parameter IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic per= + IDEAS.Fluid.PVTCollectors.Data.Uncovered.UI_Validation() + "Performance data" annotation (choicesAllMatching=true); + Modelica.Blocks.Sources.Sine T1( + amplitude=15, + f=0.1, + offset=273.15 + 10) "Temperature of the first segment" + annotation (Placement(transformation(extent={{-92,-22},{-72,-2}}))); + Modelica.Blocks.Sources.Sine T2( + f=0.1, + amplitude=15, + offset=273.15 + 15) "Temperature of the second segment" + annotation (Placement(transformation(extent={{-68,-36},{-48,-16}}))); + Modelica.Blocks.Sources.Sine T3( + f=0.1, + amplitude=15, + offset=273.15 + 20) "Temperature of the third segment" + annotation (Placement(transformation(extent={{-90,-52},{-70,-32}}))); + ISO9806QuasiDynamicHeatLoss heaLosQuaDyn( + nSeg=3, + redeclare package Medium = IDEAS.Media.Water, + c1=per.c1, + c2=per.c2, + c3=per.c3, + c4=per.c4, + c6=per.c6, + A_c=per.A) annotation (Placement(transformation(extent={{18,-2},{38,18}}))); + + SolarCollectors.BaseClasses.EN12975HeatLoss heaLosSteSta( + A_c=per.A, + nSeg=3, + redeclare package Medium = IDEAS.Media.Water, + a1=per.c1, + a2=per.c2) + annotation (Placement(transformation(extent={{18,-68},{38,-48}}))); + Modelica.Blocks.Sources.Sine TEnv( + f=0.01, + offset=273.15 + 10, + amplitude=15) "Temperature of the surrounding environment" + annotation (Placement(transformation(extent={{-80,24},{-60,44}}))); + Modelica.Blocks.Sources.Sine winSpePla( + f=1/(24*3600), + phase=0, + offset=3, + amplitude=5) "wind speed in the collector plane" + annotation (Placement(transformation(extent={{60,58},{80,78}}))); + Modelica.Blocks.Sources.RealExpression HHorIR(y=400) "long wave irradiance" + annotation (Placement(transformation(extent={{-1.5,58},{17.5,74}}))); + Modelica.Blocks.Interfaces.RealOutput QLos_flow_QuaDyn[3] + "Limited heat loss rate at current conditions" + annotation (Placement(transformation(extent={{60,-2},{80,18}}))); + Modelica.Blocks.Interfaces.RealOutput QLos_flow_SteSta[3] + "Limited heat loss rate at current conditions" + annotation (Placement(transformation(extent={{62,-68},{82,-48}}))); + Modelica.Blocks.Sources.RealExpression HGloTil(y=800) "long wave irradiance" + annotation (Placement(transformation(extent={{26.5,58},{45.5,74}}))); +equation + connect(winSpePla.y, heaLosQuaDyn.winSpePla); + connect(HHorIR.y, heaLosQuaDyn.HHorIR); + connect(HGloTil.y, heaLosQuaDyn.HGloTil); + connect(T3.y, heaLosQuaDyn.TFlu[3]) annotation (Line(points={{-69,-42},{-44,-42}, + {-44,2},{-20,2},{-20,2.66667},{16,2.66667}}, + color={0,0,127})); + connect(T2.y, heaLosQuaDyn.TFlu[2]) annotation (Line(points={{-47,-26},{-44,-26}, + {-44,2},{16,2}}, color={0,0,127})); + connect(TEnv.y, heaLosQuaDyn.TEnv) annotation (Line(points={{-59,34},{8,34},{8, + 14},{16,14}}, color={0,0,127})); + connect(heaLosSteSta.TEnv, TEnv.y) annotation (Line(points={{16,-52},{8,-52},{ + 8,34},{-59,34}}, color={0,0,127})); + connect(T1.y, heaLosSteSta.TFlu[1]) annotation (Line(points={{-71,-12},{-68, + -12},{-68,2},{-44,2},{-44,-64.6667},{16,-64.6667}}, + color={0,0,127})); + connect(T2.y, heaLosSteSta.TFlu[2]) annotation (Line(points={{-47,-26},{-44,-26}, + {-44,-64},{16,-64}}, color={0,0,127})); + connect(T3.y, heaLosSteSta.TFlu[3]) annotation (Line(points={{-69,-42},{-44, + -42},{-44,-63.3333},{16,-63.3333}}, + color={0,0,127})); + connect(T1.y, heaLosQuaDyn.TFlu[1]) annotation (Line(points={{-71,-12},{-68,-12}, + {-68,1.33333},{16,1.33333}}, color={0,0,127})); + connect(heaLosQuaDyn.QLos_flow, QLos_flow_QuaDyn) + annotation (Line(points={{39,8},{70,8}}, color={0,0,127})); + connect(heaLosSteSta.QLos_flow, QLos_flow_SteSta) + annotation (Line(points={{39,-58},{72,-58}}, color={0,0,127})); + annotation ( + Documentation(info=" +

+This example demonstrates the implementation of + +IDEAS.Fluid.PVTCollectors.BaseClasses.ISO9806QuasiDynamicHeatLoss, +which calculates the quasi-dynamic heat loss of a PVT or solar thermal collector +according to the ISO 9806:2013 standard. +

+ +

+In addition to showcasing the ISO 9806-based model, this example also compares its behavior +to the steady-state heat loss model + +IDEAS.Fluid.SolarCollectors.BaseClasses.EN12975HeatLoss, +which is based on the now-superseded EN 12975 standard. +

+ +

+This comparison highlights the differences between the steady-state and quasi-dynamic +approaches, particularly in how they account for environmental factors such as wind speed +and long-wave irradiance. +

+", +revisions=" + +"), experiment(Tolerance=1e-6, StopTime=100)); +end ISO9806HeatLoss; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.mo index 42319f94c8..1d672686e4 100644 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.mo +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.mo @@ -1,4 +1,4 @@ -within IDEAS.Fluid.PvtCollectors.BaseClasses; +within IDEAS.Fluid.PVTCollectors.BaseClasses; package Examples "Collection of models that illustrate model use and test models" extends Modelica.Icons.ExamplesPackage; @@ -6,8 +6,19 @@ extends Modelica.Icons.ExamplesPackage; annotation (preferredView="info", Documentation(info="

This package contains examples for the use of models that can be found in - + IDEAS.Fluid.PvtCollectors.BaseClasses.

+", +revisions=" + ")); end Examples; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.order b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.order index cd85418950..8a06bfc919 100644 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.order +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/Examples/package.order @@ -1 +1 @@ -EN12975HeatLoss_QD +ISO9806HeatLoss diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/ISO9806QuasiDynamicHeatLoss.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/ISO9806QuasiDynamicHeatLoss.mo new file mode 100644 index 0000000000..26b9d1e5bb --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/ISO9806QuasiDynamicHeatLoss.mo @@ -0,0 +1,115 @@ +within IDEAS.Fluid.PVTCollectors.BaseClasses; +model ISO9806QuasiDynamicHeatLoss + "Calculate the heat loss of a PVT/solar collector per ISO9806:2013" + + extends IDEAS.Fluid.SolarCollectors.BaseClasses.EN12975HeatLoss( + // Override the internal heat-loss expression to include c3, c4 and c6 terms + QLos_internal=A_c/nSeg*{dT[i]*(c1 - c2*dT[i] + c3*winSpePla) + c4*(HHorIR + - sigma*TEnv^4) - c6*winSpePla*HGloTil for i in 1:nSeg}, + // Map original a1, a2 to renamed c1, c2 + a1=c1, + a2=c2); + + // —— Renamed EN12975 coefficients —— + parameter Modelica.Units.SI.CoefficientOfHeatTransfer c1(final min=0) + "Linear heat loss coefficient (alias for a1)"; + parameter Real c2(final unit="W/(m2.K2)", final min=0) + "Quadratic heat loss coefficient (alias for a2)"; + + // —— Additional quasi-dynamic coefficients —— + parameter Modelica.Units.SI.SpecificHeatCapacity c3(final min=0) + "Wind-speed dependence of heat loss"; + parameter Modelica.Units.SI.DimensionlessRatio c4(final min=0) + "Sky long-wave irradiance dependence"; + parameter Real c6(final unit="s/m", final min=0) + "Windspeed dependence of thermal zero-loss efficiency"; + + // —— Physical constant —— + parameter Real sigma = 5.67e-8 + "Stefan–Boltzmann constant [W/m².K⁴]"; + + // Quasi-dynamic inputs + Modelica.Blocks.Interfaces.RealInput winSpePla( + quantity="Windspeed", + unit="m/s", + displayUnit="m/s") + "Wind speed normal to collector plane"; + Modelica.Blocks.Interfaces.RealInput HGloTil( + quantity="Global solar irradiance", + unit="W/m2", + displayUnit="W/m2") + "Global irradiance on tilted plane"; + Modelica.Blocks.Interfaces.RealInput HHorIR( + quantity="Long-wave solar irradiance", + unit="W/m2", + displayUnit="W/m2") "Long-wave (sky) irradiance [W/m2]" annotation ( + Placement(transformation( + extent={{-20,-20},{20,20}}, + rotation=0, + origin={-120,0}), iconTransformation(extent={{-140,-20},{-100,20}}))); + +annotation ( +defaultComponentName="heaLosStc", +Documentation(info=" +

+This component computes the quasi-dynamic heat loss from a solar thermal or PVT collector +to the environment, following the methodology described in the international standard +ISO 9806:2013. It extends the original EN12975HeatLoss model for code reuse, +but implements the more comprehensive quasi-dynamic formulation. +

+ +

+The heat loss is calculated for each segment i ∈ {1, ..., nseg} as: +

+ +

+Qlos,i = Ac / nseg · [ΔTi · (c1 - c2 · ΔTi + c3 · u) + c4 · (EL - σ · Tenv4) - c6 · u · G] +

+ +

+where: +

+

+ +

+This model provides a more accurate representation of collector heat loss under dynamic environmental conditions, +as required by ISO 9806:2013. It is suitable for use in simulations where wind speed, sky radiation, and irradiance +vary over time. +

+ +

Implementation Notes

+

+The model inherits from IDEAS.Fluid.SolarCollectors.BaseClasses.EN12975HeatLoss for structural consistency and reuse of base functionality, +but the naming and equations have been updated to reflect the ISO 9806 standard. Parameters a1 and a2 +are internally mapped to c1 and c2 for clarity. +

+ +

References

+

+ISO 9806:2013, Solar energy — Solar thermal collectors — Test methods
+Duffie, J.A., and Beckman, W.A., Solar Engineering of Thermal Processes, 4th ed., Wiley, 2013 +

+", +revisions=" + +")); +end ISO9806QuasiDynamicHeatLoss; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/PartialEN12975HeatLoss_QuasiDynamic.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/PartialEN12975HeatLoss_QuasiDynamic.mo deleted file mode 100644 index 2b16f07e5a..0000000000 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/PartialEN12975HeatLoss_QuasiDynamic.mo +++ /dev/null @@ -1,55 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.BaseClasses; -block PartialEN12975HeatLoss_QuasiDynamic - "Model to calculate the quasi-dynamic heat loss of a pvt/solar collector following the ISO 9806:2013 quasi-dynamic method" - extends IDEAS.Fluid.PvtCollectors.BaseClasses.EN12975HeatLoss_SteadyState( - QLos_internal=A_c/nSeg*{dT[i] * (c1 - c2 * dT[i] + c3*u) + c4*(E_L - sigma*TEnv^4) - - c6*u*G for i in 1:nSeg}); - -// Constants - parameter Real c3(final unit = "J/(m3.K)", final min=0) "a3 from ratings data"; - parameter Real c4(final unit = "", final min=0) "c4 from ratings data"; - parameter Real c6(final unit = "J/(m3.K)", final min=0) "c6 from ratings data"; - parameter Real sigma = 5.67e-8 "Stefan-Boltzmann constant [W/m²K^4]"; - - // Inputs - Modelica.Blocks.Interfaces.RealInput u( - quantity="Windspeed", - unit="m/s", - displayUnit="m/s") "windspeed of surrounding air" - annotation (Placement(transformation(extent={{-142,0},{-100,42}}), - iconTransformation(extent={{-142,0},{-100,42}}))); - Modelica.Blocks.Interfaces.RealInput E_L( - quantity="long-wave solar irradiance", - unit="W/m2", - displayUnit="W/m2") "Long-wave solar irradiance [W/m2]" annotation (Placement( - transformation(extent={{-21,-21},{21,21}}, - rotation=0, - origin={-121,-99}), iconTransformation( - extent={{-142,-120},{-100,-78}}))); - - Modelica.Blocks.Interfaces.RealInput G( - quantity="Global solar irradiance", - unit="W/m2", - displayUnit="W/m2") "global solar irradiance [W/m2]" annotation (Placement( - transformation(extent={{-21,-21},{21,21}}, - rotation=0, - origin={-121,-21}), iconTransformation( - extent={{-140,-42},{-98,0}}))); - - // Internal variables to be visible in simulation results - Real c1_c2_term(unit="W"); - Real c3_term(unit="W"); - Real c4_term(unit="W"); - Real c6_term(unit="W"); - - // Equations for terms -equation - c1_c2_term = sum(A_c/nSeg*{dT[i]*(c1 - c2*dT[i]) for i in 1:nSeg}); - c3_term = sum(A_c/nSeg*{dT[i]*(c3*u) for i in 1:nSeg}); - c4_term = sum(A_c/nSeg*{c4*(E_L - sigma*TEnv^4) for i in 1:nSeg}); - c6_term = sum(A_c/nSeg*{(-1)* c6*u*G for i in 1:nSeg}); - - annotation (Documentation(info=" -

Model to calculate the quasi-dynamic heat loss of a pvt/solar collector following the ISO 9806:2013 quasi-dynamic method.

-")); -end PartialEN12975HeatLoss_QuasiDynamic; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/PartialPvtCollector.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/PartialPvtCollector.mo deleted file mode 100644 index f3007f069a..0000000000 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/PartialPvtCollector.mo +++ /dev/null @@ -1,88 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.BaseClasses; -model PartialPvtCollector - "Extended partial solar (thermal) collector with discretized PV electrical calculations" - extends IDEAS.Fluid.SolarCollectors.BaseClasses.PartialSolarCollector( - redeclare IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic per); - - // ===== Parameters ===== - final parameter Modelica.Units.SI.Irradiance Gstc = 1000 - "Irradiance at Standard Conditions (W/m2)"; - parameter Modelica.Units.SI.Efficiency pLossFactor = 0.10 - "Loss factor of the PV panel(s)" annotation(Dialog(group="Electrical parameters")); - constant Modelica.Units.SI.Temperature _T_ref = 25 + 273 - "Reference cell temperature (K)"; - parameter IDEAS.Fluid.PvtCollectors.Types.CollectorType collectorType = - IDEAS.Fluid.PvtCollectors.Types.CollectorType.Uncovered - "Type of collector (used to select (tau*alpha)_eff)"; - parameter Real tauAlphaEff = - if collectorType == IDEAS.Fluid.PvtCollectors.Types.CollectorType.Uncovered then 0.901 else 0.84 - "Effective transmittance–absorptance product"; - output Modelica.Units.SI.CoefficientOfHeatTransfer UAbsFluidCalc = - ((tauAlphaEff - per.eta0El) * (per.c1 + abs(per.gamma)*Gstc)) - / ((tauAlphaEff - per.eta0El) - per.eta0) - "Heat transfer coefficient calculated from datasheet parameters"; - - // ===== Variables ===== - - Real Tm[nSeg] "Mean fluid temperature for each segment"; - Real temCell[nSeg] "Cell temperature for each segment (K)"; - Real temDiff[nSeg] "Temperature difference of the cell relative to reference (K)"; - Real G "Global irradiance on the panel (W/m2)"; - Real qth[nSeg] "Thermal power density per segment [W/m2]"; - Real temMod "Average cell temperature"; - Real temMea "Average fluid temperature"; - - - // ===== Real Output Connectors ===== - Modelica.Blocks.Interfaces.RealOutput pel - "Electrical power generated by the photovoltaic installation" - annotation(Placement(transformation(extent={{100,70},{120,90}}), - iconTransformation(extent={{100,70},{120,90}}))); - Modelica.Blocks.Interfaces.RealOutput qTh - "Total thermal power generated by the PVT installation" - annotation(Placement(transformation(extent={{100,-90},{120,-70}}))); - - Modelica.Blocks.Interfaces.RealOutput solarPowerInternal[nSeg] - "Electrical power produced by each discretized PV segment (W)"; - Modelica.Blocks.Math.Add gGlob "Total irradiation on tilted surface" - annotation (Placement(transformation( - extent={{10,-10},{-10,10}}, - rotation=90, - origin={24,78}))); -equation - // Directly calculate global irradiance from measurement data - G =gGlob.y; - - // Calculate PV electrical performance for each segment - for i in 1:nSeg loop - // Retrieve the mean fluid temperature from the sensor array (provided by the base model) - Tm[i] = temSen[i].T; - // Compute the local thermal power density (W/m2) - qth[i] = (QGai[i].Q_flow + QLos[i].Q_flow) / (ATot_internal/nSeg); - // Estimate the cell temperature using fluid temperature and thermal flux - temCell[i] = Tm[i] + qth[i] / UAbsFluidCalc; - // Determine the temperature difference relative to the reference temperature - temDiff[i] = temCell[i] - _T_ref; - // Calculate electrical power output per segment using the PV performance equation - solarPowerInternal[i] = (ATot_internal/nSeg) * (per.Pstc/per.A) * (G/Gstc) * - (1 + per.gamma*temDiff[i]) * (1 - pLossFactor); - - end for; - - // Assign the sum of the segment electrical outputs to the output connector pel - pel = sum(solarPowerInternal); - - // Calculate the total thermal power by multiplying the thermal density with the segment area and summing up - qTh = (ATot_internal/nSeg) * sum(qth); - - // Calculate the average cell temperature, defined as module temperature - temMod = sum(temCell)/nSeg; - - // Calculate the average fluid temperature, defined as module temperature - temMea = sum(Tm)/nSeg; - - connect(gGlob.u1, HDirTil.H) annotation (Line(points={{18,90},{-54,90},{-54,50}, - {-59,50}}, color={0,0,127})); - connect(gGlob.u2, HDifTilIso.H) annotation (Line(points={{30,90},{30,98},{-54, - 98},{-54,92},{-56,92},{-56,80},{-59,80}}, color={0,0,127})); -end PartialPvtCollector; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/package.mo b/IDEAS/Fluid/PvtCollectors/BaseClasses/package.mo index 3cc60117f7..c3fedd44ca 100644 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/package.mo +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/package.mo @@ -1,11 +1,22 @@ -within IDEAS.Fluid.PvtCollectors; +within IDEAS.Fluid.PVTCollectors; package BaseClasses "Package with base classes for IDEAS.Fluid.PvtCollectors" extends Modelica.Icons.BasesPackage; annotation (preferredView="info", Documentation(info="

This package contains base classes that are used to construct the models in - IDEAS.Fluid.PvtCollectors. + IDEAS.Fluid.PvtCollectors.

+", +revisions=" + ")); end BaseClasses; diff --git a/IDEAS/Fluid/PvtCollectors/BaseClasses/package.order b/IDEAS/Fluid/PvtCollectors/BaseClasses/package.order index e070c65ccb..841c049367 100644 --- a/IDEAS/Fluid/PvtCollectors/BaseClasses/package.order +++ b/IDEAS/Fluid/PvtCollectors/BaseClasses/package.order @@ -1,5 +1,3 @@ -EN12975HeatLoss_QuasiDynamic +ElectricalPVT +ISO9806QuasiDynamicHeatLoss Examples -PartialEN12975HeatLoss_QuasiDynamic -PartialPvtCollector -EN12975HeatLoss_SteadyState diff --git a/IDEAS/Fluid/PvtCollectors/Data/Concentrating/U_TRNSYSValidation.mo b/IDEAS/Fluid/PvtCollectors/Data/Concentrating/U_TRNSYSValidation.mo deleted file mode 100644 index 8a64659b57..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Data/Concentrating/U_TRNSYSValidation.mo +++ /dev/null @@ -1,56 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.Data.Concentrating; -record U_TRNSYSValidation = - IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic( - final A = 1.66, - final CTyp = IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, - final C = 42200 * 1.66, - final V = 5 / 1000, - final mDry = 28, - final mperA_flow_nominal = 0.03, - final dp_nominal = 60000, - final incAngDat = Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), - final incAngModDat = {1,1,1,0.99,0.99,0.98,0.96,0.92,0.00}, - final IAMDiff = 1, - final eta0 = 0.475, - final c1 = 7.411, - final c2 = 0.0, - final c3 = 1.7, - final c4 = 0.437, - final c6 = 0.003) "SRCC-validated performance parameters for an uncovered (unglazed) flat-plate PVT collector, Solar Keymark Certificate 011-7S2782P" -annotation( - defaultComponentPrefixes = "parameter", - defaultComponentName = "datWiscPvt", - Documentation(info = " -

-This record contains performance parameters for an uncovered (WISC) flat-plate PVT collector, -tested under ISO 9806:2013 quasi-dynamic conditions (Solar Keymark Certificate No. 011-7S2782P). Thermal performance parameters are given for the PV module operating -at maximum power point (MPP mode). Data retrieved from the Solar Keymark database on certified PVT products. -

-

Certificate

- -

References

- -", - revisions = " - -")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Concentrating/package.order b/IDEAS/Fluid/PvtCollectors/Data/Concentrating/package.order deleted file mode 100644 index 57beaba965..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Data/Concentrating/package.order +++ /dev/null @@ -1 +0,0 @@ -U_TRNSYSValidation diff --git a/IDEAS/Fluid/PvtCollectors/Data/Covered/CI_Jonas2018_ParamSet.mo b/IDEAS/Fluid/PvtCollectors/Data/Covered/CI_Jonas2018_ParamSet.mo new file mode 100644 index 0000000000..fd05c0cf7b --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Data/Covered/CI_Jonas2018_ParamSet.mo @@ -0,0 +1,55 @@ +within IDEAS.Fluid.PVTCollectors.Data.Covered; +record CI_Jonas2018_ParamSet + = + IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic( + final A=1.79, + final CTyp=IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, + final C=16631*1.79, + final V=5/1000, + final mDry=26, + final mperA_flow_nominal=0.03, + final dp_nominal=60000, + final incAngDat=Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), + final incAngModDat={1,1,0.99,0.98,0.97,0.95,0.92,0.88,0.00}, + final IAMDiff=0.94, + final eta0=0.573, + final c1=5.008, + final c2=0.059, + final c3=0.011, + final c4=0.039, + final c6=0.003, + final P_nominal=280, + final gamma=-0.00370, + final etaEl=0.1390) + "Parameter set for a covered, insulated PVT collector based on Jonas et al. (2018)" +annotation( + defaultComponentPrefixes = "parameter", + defaultComponentName = "datPVTCol", + Documentation(info = " +

+This record contains thermal and electrical parameters for a covered and insulated PVT collector, based on experimental identification results from Jonas et al. (2018). +These parameters were used in the validation of a TRNSYS PVT collector model under ISO 9806:2013 quasi-dynamic conditions. +

+

+This record can be used as a generic representation of a covered, insulated PVT collector. +However, if you know the brand and model of the PVT collector you plan to simulate or install, +it is recommended to use the actual datasheet parameters in a custom IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic record. +

+

Reference

+ +", +revisions=" + +")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Covered/CN_Jonas2018_ParamSet.mo b/IDEAS/Fluid/PvtCollectors/Data/Covered/CN_Jonas2018_ParamSet.mo new file mode 100644 index 0000000000..0255f99245 --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Data/Covered/CN_Jonas2018_ParamSet.mo @@ -0,0 +1,56 @@ +within IDEAS.Fluid.PVTCollectors.Data.Covered; +record CN_Jonas2018_ParamSet + = + IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic( + final A=1.79, + final CTyp=IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, + final C=16075*1.79, + final V=5/1000, + final mDry=24, + final mperA_flow_nominal=0.03, + final dp_nominal=60000, + final incAngDat=Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), + final incAngModDat={1,1,0.99,0.98,0.97,0.95,0.92,0.88,0.00}, + final IAMDiff=0.93, + final eta0=0.596, + final c1=6.583, + final c2=0.021, + final c3=0.000, + final c4=0.066, + final c6=0.009, + final P_nominal=280, + final gamma=-0.00370, + final etaEl=0.1406) + "Parameter set for a covered, non-insulated PVT collector based on Jonas et al. (2018)" +annotation( + defaultComponentPrefixes = "parameter", + defaultComponentName = "datPVTCol", + Documentation(info = " +

+This record contains thermal and electrical parameters for a covered PVT collector without rear insulation, +based on experimental identification results from Jonas et al. (2018). +These parameters were used in the validation of a TRNSYS PVT collector model under ISO 9806:2013 quasi-dynamic conditions. +

+

+This record can be used as a generic representation of a covered, non-insulated PVT collector. +However, if you know the brand and model of the PVT collector you plan to simulate or install, +it is recommended to use the actual datasheet parameters in a custom IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic record. +

+

Reference

+ +", +revisions=" + +")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Covered/package.mo b/IDEAS/Fluid/PvtCollectors/Data/Covered/package.mo index c703fd9668..5448d583ee 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/Covered/package.mo +++ b/IDEAS/Fluid/PvtCollectors/Data/Covered/package.mo @@ -1,4 +1,4 @@ -within IDEAS.Fluid.PvtCollectors.Data; +within IDEAS.Fluid.PVTCollectors.Data; package Covered "Performance data for covered PVT collectors" extends Modelica.Icons.MaterialPropertiesPackage; @@ -18,6 +18,17 @@ ISO 9806:2013 quasi-dynamic testing, with parameters sourced from Solar Keymark Certificate. Thermal performance parameters apply to the PV module in maximum power point (MPP) operation mode.

+", +revisions=" + ")); end Covered; diff --git a/IDEAS/Fluid/PvtCollectors/Data/Covered/package.order b/IDEAS/Fluid/PvtCollectors/Data/Covered/package.order index e69de29bb2..e387f51943 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/Covered/package.order +++ b/IDEAS/Fluid/PvtCollectors/Data/Covered/package.order @@ -0,0 +1,2 @@ +CI_Jonas2018_ParamSet +CN_Jonas2018_ParamSet diff --git a/IDEAS/Fluid/PvtCollectors/Data/GenericQuasiDynamic.mo b/IDEAS/Fluid/PvtCollectors/Data/GenericQuasiDynamic.mo index 5d5309d682..da8230e193 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/GenericQuasiDynamic.mo +++ b/IDEAS/Fluid/PvtCollectors/Data/GenericQuasiDynamic.mo @@ -1,4 +1,4 @@ -within IDEAS.Fluid.PvtCollectors.Data; +within IDEAS.Fluid.PVTCollectors.Data; record GenericQuasiDynamic "Generic data record for PVT collector models" extends IDEAS.Fluid.SolarCollectors.Data.BaseClasses.Generic; @@ -7,27 +7,26 @@ record GenericQuasiDynamic "Incidence angle modifier for diffuse irradiance (incidence angle of 50°)"; parameter Real eta0(final min=0, final max=1, final unit="1") "Optical thermal efficiency (Maximum efficiency)"; - parameter Real c1(final min=0, final unit="W/(m2.K)") + parameter Modelica.Units.SI.CoefficientOfHeatTransfer c1(final min=0) "First order thermal heat loss coefficient"; parameter Real c2(final min=0, final unit="W/(m2.K2)") "Second order thermal heat loss coefficient"; - parameter Real c3(final min=0, final unit="J/(m3.K)") - "Windspeed dependence of thermal heat losses"; - parameter Real c4(final min=0, final unit="1") - "Sky temperature dependence of the thermal heat-loss coefficient"; + parameter Modelica.Units.SI.SpecificHeatCapacity c3(final min=0) + "Windspeed dependence of thermal heat loss"; + parameter Modelica.Units.SI.DimensionlessRatio c4(final min=0) + "Sky temperature dependence of the thermal heat loss coefficient"; parameter Real c6(final min=0, final unit="s/m") "Windspeed dependence of thermal zero-loss efficiency"; - parameter Real Pstc(final min=0, final unit="W") - "PV panel power at STC (W)"; - parameter Real gamma(final unit="1/K") + parameter Real P_nominal(final min=0, final unit="W") + "PV panel power at nominal conditions (W)"; + parameter Modelica.Units.SI.LinearTemperatureCoefficient gamma "Temperature coefficient of the PV panel(s)"; - parameter Real eta0El(final min=0, final max=1, final unit="1") + parameter Modelica.Units.SI.Efficiency etaEl(final min=0, final max=1) "Module efficiency of the photovoltaic installation"; - annotation ( defaultComponentPrefixes="parameter", -defaultComponentName="datPvtCol", +defaultComponentName="datPVTCol", Documentation(info="

Record containing both thermal and electrical performance parameters for PVT @@ -37,22 +36,24 @@ electrical parameters and system loss factors follow from the manufacturer datas

References

-", evisions = " - +", +revisions=" + ")); end GenericQuasiDynamic; diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UI_TRNSYSValidation.mo b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UI_TRNSYSValidation.mo deleted file mode 100644 index 9cc6231f5a..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UI_TRNSYSValidation.mo +++ /dev/null @@ -1,54 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.Data.Uncovered; -record UI_TRNSYSValidation= - IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic( - final A = 1.66, - final CTyp = IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, - final C = 42200 * 1.66, - final V = 5 / 1000, - final mDry = 28, - final mperA_flow_nominal = 0.03, - final dp_nominal = 60000, - final incAngDat = Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), - final incAngModDat = {1,1,1,0.99,0.99,0.98,0.96,0.92,0.00}, - final IAMDiff = 1, - final eta0 = 0.475, - final c1 = 7.411, - final c2 = 0.0, - final c3 = 1.7, - final c4 = 0.437, - final c6 = 0.003, - final Pstc = 280, - final gamma = -0.0041, - final eta0El = 0.1687) - "Parameters for an uncovered flat-plate PVT collector with rear cover and back-side thermal insulation" -annotation( - defaultComponentPrefixes = "parameter", - defaultComponentName = "datPvtCol", - Documentation(info = " -

-This record contains anonymized thermal and electrical performance parameters for an uncovered photovoltaic–thermal (PVT) collector with rear insulation, -tested under ISO 9806:2013 quasi-dynamic conditions. Thermal performance parameters correspond to operation -of the PV module at maximum power point (MPP mode). -

- -

References

- - -", - revisions = " - -")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UI_Validation.mo b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UI_Validation.mo new file mode 100644 index 0000000000..e955b261bb --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UI_Validation.mo @@ -0,0 +1,66 @@ +within IDEAS.Fluid.PVTCollectors.Data.Uncovered; +record UI_Validation = + IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic( + final A=1.66, + final CTyp=IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, + final C=42200*1.66, + final V=5/1000, + final mDry=28, + final mperA_flow_nominal=0.03, + final dp_nominal=60000, + final incAngDat=Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), + final incAngModDat={1,1,1,0.99,0.99,0.98,0.96,0.92,0.00}, + final IAMDiff=1, + final eta0=0.475, + final c1=7.411, + final c2=0.0, + final c3=1.7, + final c4=0.437, + final c6=0.003, + final P_nominal=280, + final gamma=-0.0041, + final etaEl=0.1687) + "Parameters for an uncovered flat-plate PVT collector with rear cover and back-side thermal insulation" +annotation( + defaultComponentPrefixes = "parameter", + defaultComponentName = "datPVTCol", + Documentation(info = " +

+This record contains anonymized thermal and electrical performance parameters for an uncovered photovoltaic–thermal (PVT) collector with rear insulation, +tested under ISO 9806:2013 quasi-dynamic conditions. Thermal performance parameters correspond to operation +of the PVT collector at maximum power point (MPP mode). +

+ +

+This datasheet is used in the validation of +IDEAS.Fluid.PVTCollectors.PVTQuasiDynamicCollector, +which can be found in the +IDEAS.Fluid.PVTCollectors.Validation.PVT1 package. +

+ + +

References

+ +", +revisions=" + +")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_Jonas2018_ParamSet.mo b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_Jonas2018_ParamSet.mo new file mode 100644 index 0000000000..cea14dc8dd --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_Jonas2018_ParamSet.mo @@ -0,0 +1,53 @@ +within IDEAS.Fluid.PVTCollectors.Data.Uncovered; +record UN_Jonas2018_ParamSet + = + IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic( + final A=1.66, + final CTyp=IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, + final C=35800*1.66, + final V=5/1000, + final mDry=20, + final mperA_flow_nominal=0.03, + final dp_nominal=60000, + final incAngDat=Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), + final incAngModDat={1,1,0.99,0.98,0.97,0.95,0.92,0.88,0.00}, + final IAMDiff=0.91, + final eta0=0.436, + final c1=7.750, + final c2=0.026, + final c3=1.640, + final c4=0.000, + final c6=0.008, + final P_nominal=280, + final gamma=-0.00467, + final etaEl=0.1688) + "Parameter set for a uncovered, non-insulated PVT collector (WISC type) based on Jonas et al. (2018)" +annotation( + defaultComponentPrefixes = "parameter", + defaultComponentName = "datPVTCol", + Documentation(info = " +

+This record contains thermal and electrical parameters for an uncovered and non-insulated PVT collector (WISC type), based on experimental identification results from Jonas et al. (2018). +These parameters were used in the validation of a TRNSYS PVT collector model under ISO 9806:2013 quasi-dynamic conditions. +

+

+This record can be used as a generic representation of a WISC-type collector. However, if you know the brand and model of the PVT collector you plan to simulate or install, it is recommended to use the actual datasheet parameters in a custom IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic record. +

+

Reference

+ +", +revisions=" + +")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_PVTHERMAU300.mo b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_PVTHERMAU300.mo deleted file mode 100644 index bdf65f50bf..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_PVTHERMAU300.mo +++ /dev/null @@ -1,74 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.Data.Uncovered; -record UN_PVTHERMAU300 = - IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic( - final A = 1.66, - final CTyp = IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, - final C = 42200 * 1.66, - final V = 5 / 1000, - final mDry = 28, - final mperA_flow_nominal = 0.03, - final dp_nominal = 60000, - final incAngDat = Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), - final incAngModDat = {1,1,1,0.99,0.99,0.98,0.96,0.92,0.00}, - final IAMDiff = 1, - final eta0 = 0.475, - final c1 = 7.411, - final c2 = 0.0, - final c3 = 1.7, - final c4 = 0.437, - final c6 = 0.003, - final Pstc = 300, - final gamma = -0.00375, - final eta0El = 0.183) - "Parameters for an uncovered flat-plate PVT collector without rear cover or back-side insulation" -annotation( - defaultComponentPrefixes = "parameter", - defaultComponentName = "datPvtCol", - Documentation(info = " -

-This record contains performance parameters for a flat‑plate, uncovered and uninsulated PVT collector, derived from manufacturer datasheets and thermal rating documentation. Thermal parameters follow the ISO 9806:2013 quasi‑dynamic format and correspond to operation at the PV module’s maximum power point (MPP). -

- -

-For this PVT collector, additional real-life measurement data is publicly available (Veynandt, 2023) and has been used in the validation of the QuasiDynamicPvtCollector PVT model (Meertens, 2025). - -

Certificate

- - -

Data conversion

-

-The thermal coefficients were originally obtained using the ISO 9806:2013 unglazed steady-state method, and converted to quasi‑dynamic form according to the Solar Keymark Network procedure (2019). -

- -

References

- - -"), - revisions = " - -"); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_Validation.mo b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_Validation.mo new file mode 100644 index 0000000000..06d190e056 --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/UN_Validation.mo @@ -0,0 +1,83 @@ +within IDEAS.Fluid.PVTCollectors.Data.Uncovered; +record UN_Validation = + IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic( + final A=1.64, + final CTyp=IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, + final C=22100*1.64, + final V=1.54/1000, + final mDry=30, + final mperA_flow_nominal=0.02, + final dp_nominal=300000, + final incAngDat=Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,80,90}), + final incAngModDat={1,1,1,1,0.99,0.97,0.92,0.80,0.55,0.00}, + final IAMDiff=0.93, + final eta0=0.535, + final c1=10.74, + final c2=0.0, + final c3=1.0997, + final c4=0.535*0.85*(1-3*0.067), + final c6=0.067*0.535, + final P_nominal=300, + final gamma=-0.00375, + final etaEl=0.183) + "Parameters for an uncovered flat-plate PVT collector without rear cover or back-side insulation" +annotation( + defaultComponentPrefixes = "parameter", + defaultComponentName = "datPVTCol", + Documentation(info = " +

+This record contains performance parameters for a flat‑plate, uncovered and uninsulated PVT collector, derived from manufacturer datasheets and thermal rating documentation. Thermal parameters follow the ISO 9806:2013 quasi‑dynamic format and correspond to operation at the PV module’s maximum power point (MPP). +

+ +

+The thermal coefficients were originally obtained using the ISO 9806:2013 unglazed +steady-state method, and converted to quasi‑dynamic form according to the procedure detailed +in +SKN-N0474R0: Thermal Performance Parameter Conversion to ISO 9806-2017. + + + +

+For this PVT collector, additional real-life measurement data is publicly available (Veynandt, 2023) and has been used in the validation of +IDEAS.Fluid.PVTCollectors.PVTQuasiDynamicCollector, +which can be found in the +IDEAS.Fluid.PVTCollectors.Validation.PVT2 package. +

+ +

Certificate

+ + +

References

+ + +"), +revisions=" + +"); diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.mo b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.mo index 634886bab8..c44e1486ab 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.mo +++ b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.mo @@ -1,10 +1,10 @@ -within IDEAS.Fluid.PvtCollectors.Data; +within IDEAS.Fluid.PVTCollectors.Data; package Uncovered "Performance data for uncovered (WISC) PVT collectors" extends Modelica.Icons.MaterialPropertiesPackage; /** - Record of SRCC-validated parameters for uncovered (WISC) PVT collectors +Record of SRCC-validated parameters for uncovered (WISC; Wind and Infrared Sensitive Collector) PVT collectors tested according to ISO 9806:2013 quasi-dynamic procedure, retrieved from Solar Keymark Certificate No. 011-7S2782P. Thermal performance parameters are given for the PV module operating at maximum power @@ -13,12 +13,23 @@ extends Modelica.Icons.MaterialPropertiesPackage; annotation ( Documentation(info = "

-This package contains thermal and electrical performance data for uncovered (WISC) photovoltaic–thermal collectors. +This package contains thermal and electrical performance data for uncovered photovoltaic–thermal collectors, also known as WISC (Wind and Infrared Sensitive Collectors). All records conform to ISO 9806:2013 quasi-dynamic thermal testing, with parameters sourced from Solar Keymark Certificates. The thermal parameters apply to the PV module operating in maximum power point (MPP) mode, and the electrical performance parameters can be retrieved from manufacturer datasheets.

+", +revisions=" + ")); end Uncovered; diff --git a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.order b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.order index fcf4c0b6e9..b506b074b9 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.order +++ b/IDEAS/Fluid/PvtCollectors/Data/Uncovered/package.order @@ -1,2 +1,3 @@ -UI_TRNSYSValidation -UN_PVTHERMAU300 +UI_Validation +UN_Jonas2018_ParamSet +UN_Validation diff --git a/IDEAS/Fluid/PvtCollectors/Data/WISC/WISC_TRNSYSValidation.mo b/IDEAS/Fluid/PvtCollectors/Data/WISC/WISC_TRNSYSValidation.mo deleted file mode 100644 index aa6ccd80ee..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Data/WISC/WISC_TRNSYSValidation.mo +++ /dev/null @@ -1,30 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.Data.WISC; -record WISC_TRNSYSValidation = - IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic ( - final A=1.66, - final CTyp=IDEAS.Fluid.SolarCollectors.Types.HeatCapacity.TotalCapacity, - final C=42200*1.66, - final V=5/1000, - final mDry=28, - final mperA_flow_nominal=0.03, - final dp_nominal=60000, - final incAngDat=Modelica.Units.Conversions.from_deg({0,10,20,30,40,50,60,70,90}), - final incAngModDat={1,1,1,0.99,0.99,0.98,0.96,0.92,0.00}, - final IAMDiff=1, - final eta0=0.475, - final c1=7.411, - final c2=0.0, - final c3=1.7, - final c4=0.437, - final c6=0.003) - annotation ( -defaultComponentPrefixes="parameter", -defaultComponentName="datPvtCol", -Documentation(info = " - -

References

-

- Ratings data taken from the - Solar Rating and Certification Corporation website. -

- ")); diff --git a/IDEAS/Fluid/PvtCollectors/Data/WISC/package.order b/IDEAS/Fluid/PvtCollectors/Data/WISC/package.order deleted file mode 100644 index c40bfd8877..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Data/WISC/package.order +++ /dev/null @@ -1 +0,0 @@ -WISC_TRNSYSValidation diff --git a/IDEAS/Fluid/PvtCollectors/Data/package.mo b/IDEAS/Fluid/PvtCollectors/Data/package.mo index d28e705ce6..1686102e85 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/package.mo +++ b/IDEAS/Fluid/PvtCollectors/Data/package.mo @@ -1,4 +1,4 @@ -within IDEAS.Fluid.PvtCollectors; +within IDEAS.Fluid.PVTCollectors; package Data "Data for photovoltaic–thermal (PVT) collectors" extends Modelica.Icons.MaterialPropertiesPackage; @@ -36,10 +36,21 @@ collector classification.

References

+", +revisions=" + ")); end Data; diff --git a/IDEAS/Fluid/PvtCollectors/Data/package.order b/IDEAS/Fluid/PvtCollectors/Data/package.order index b221fc7e3d..61ff421538 100644 --- a/IDEAS/Fluid/PvtCollectors/Data/package.order +++ b/IDEAS/Fluid/PvtCollectors/Data/package.order @@ -1,3 +1,3 @@ GenericQuasiDynamic -Uncovered Covered +Uncovered diff --git a/IDEAS/Fluid/PvtCollectors/Examples/Wisc.mo b/IDEAS/Fluid/PvtCollectors/Examples/Wisc.mo index 250e86090e..f0742a02db 100644 --- a/IDEAS/Fluid/PvtCollectors/Examples/Wisc.mo +++ b/IDEAS/Fluid/PvtCollectors/Examples/Wisc.mo @@ -1,5 +1,5 @@ -within IDEAS.Fluid.PvtCollectors.Examples; -model Wisc "Test model for uncovered (WISC) PVT collectors" +within IDEAS.Fluid.PVTCollectors.Examples; +model WISC "Test model for WISC (Wind and Infrared Sensitive Collector) - uncovered PVT collectors" extends Modelica.Icons.Example; replaceable package Medium = Modelica.Media.Incompressible.Examples.Glycol47 "Medium in the system"; @@ -36,7 +36,7 @@ model Wisc "Test model for uncovered (WISC) PVT collectors" amplitude=-pvtCol.dp_nominal, offset=1E5) "Pressure source" annotation (Placement(transformation(extent={{-88,-18},{-68,2}}))); - QuasiDynamicPvtCollector pvtCol( + IDEAS.Fluid.PVTCollectors.PVTQuasiDynamicCollector pvtCol( redeclare package Medium = Medium, show_T=true, azi=0, @@ -45,9 +45,9 @@ model Wisc "Test model for uncovered (WISC) PVT collectors" nColType=IDEAS.Fluid.SolarCollectors.Types.NumberSelection.Number, nPanels=1, per=datPvtCol, - collectorType=IDEAS.Fluid.PvtCollectors.Types.CollectorType.Uncovered) + collectorType=IDEAS.Fluid.PVTCollectors.Types.CollectorType.Uncovered) annotation (Placement(transformation(extent={{0,-10},{20,10}}))); - parameter Data.Uncovered.UI_TRNSYSValidation datPvtCol + parameter IDEAS.Fluid.PVTCollectors.Data.Uncovered.UI_Validation datPvtCol annotation (Placement(transformation(extent={{64,64},{84,84}}))); equation connect(sou.ports[1], TIn.port_a) annotation (Line( @@ -67,27 +67,37 @@ equation connect(pvtCol.port_b, TOut.port_a) annotation (Line(points={{20,0},{32,0}}, color={0,127,255})); annotation ( - Documentation(info=" + Documentation(info="

-This example demonstrates the implementation of - -IDEAS.Fluid.PvtCollectors.QuasiDynamicPvtCollector +This example demonstrates the implementation of the + +IDEAS.Fluid.PVTCollectors.PVTQuasiDynamicCollector for a variable fluid flow rate and weather data from San Francisco, CA, USA.

+ +

+The collector modeled here is an uncovered PVT collector, also referred to as a +WISC (Wind and Infrared Sensitive Collector). These collectors are sensitive to +ambient wind and infrared radiation due to the absence of a glazing layer. +They can be either unglazed insulated (UI) or unglazed non-insulated (UN), +depending on the thermal insulation applied to the back side of the collector. +

+ +

+This test model uses the Uncovered.UI_Validation record. +However, if you know the brand and model of the PVT collector you plan to simulate or install, +it is recommended to use the actual datasheet parameters in a custom Data.GenericQuasiDynamic record. +

", revisions=" - -"), -__Dymola_Commands(file="modelica://IDEAS/Resources/Scripts/Dymola/Fluid/SolarCollectors/Examples/FlatPlate.mos" - "Simulate and plot"), - experiment(Tolerance=1e-6, StopTime=86400.0)); -end Wisc; + +"),experiment(Tolerance=1e-6, StopTime=86400.0)); +end WISC; diff --git a/IDEAS/Fluid/PvtCollectors/Examples/package.mo b/IDEAS/Fluid/PvtCollectors/Examples/package.mo index 4c4e264e9c..993cbbb449 100644 --- a/IDEAS/Fluid/PvtCollectors/Examples/package.mo +++ b/IDEAS/Fluid/PvtCollectors/Examples/package.mo @@ -1,20 +1,22 @@ -within IDEAS.Fluid.PvtCollectors; -package Examples "Examples demonstrating the use of models in the PvtCollectors package" +within IDEAS.Fluid.PVTCollectors; +package Examples "Examples demonstrating the use of models in the PVTCollectors package" extends Modelica.Icons.ExamplesPackage; - - - - - - - - - annotation(Documentation(info="

This package contains example model demonstrating the use of models in - the PvtCollectors package. + the PVTCollectors package.

- ")); + ", +revisions=" + +")); end Examples; diff --git a/IDEAS/Fluid/PvtCollectors/Examples/package.order b/IDEAS/Fluid/PvtCollectors/Examples/package.order index 9d5070ea87..8793722738 100644 --- a/IDEAS/Fluid/PvtCollectors/Examples/package.order +++ b/IDEAS/Fluid/PvtCollectors/Examples/package.order @@ -1 +1 @@ -Wisc +WISC diff --git a/IDEAS/Fluid/PvtCollectors/PvtQuasiDynamicCollector.mo b/IDEAS/Fluid/PvtCollectors/PvtQuasiDynamicCollector.mo new file mode 100644 index 0000000000..d048258137 --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/PvtQuasiDynamicCollector.mo @@ -0,0 +1,216 @@ +within IDEAS.Fluid.PVTCollectors; +model PVTQuasiDynamicCollector + "Model of a photovoltaic–thermal (PVT) collector using the ISO 9806:2013 quasi-dynamic thermal method with integrated electrical coupling" + + extends IDEAS.Fluid.SolarCollectors.BaseClasses.PartialSolarCollector( + redeclare IDEAS.Fluid.PVTCollectors.Data.GenericQuasiDynamic per); + + // ===== Parameters ===== + parameter Modelica.Units.SI.Efficiency pLossFactor = 0.10 + "Loss factor of the PV panel(s)" annotation(Dialog(group="Electrical parameters")); + parameter IDEAS.Fluid.PVTCollectors.Types.CollectorType collectorType = IDEAS.Fluid.PVTCollectors.Types.CollectorType.Uncovered + "Type of collector (used to select (tau*alpha)_eff)"; + parameter Modelica.Units.SI.DimensionlessRatio tauAlphaEff = + (if collectorType == IDEAS.Fluid.PVTCollectors.Types.CollectorType.Uncovered then 0.901 else 0.84) + "Effective transmittance–absorptance product"; + + // ===== Output Connectors ===== + Modelica.Blocks.Interfaces.RealOutput pEl + "Total electrical power output [W/m2]" + annotation (Placement(transformation(extent={{100,-60},{120,-40}}), + iconTransformation(extent={{100,-60},{120,-40}}))); + Modelica.Blocks.Interfaces.RealOutput qTh "Total thermal power output [W/m2]" + annotation (Placement(transformation(extent={{100,-100},{120,-80}}), + iconTransformation(extent={{100,-100},{120,-80}}))); + Modelica.Blocks.Interfaces.RealOutput winSpeTil "Effective wind speed normal to collector plane"; + Modelica.Blocks.Interfaces.RealInput qThSeg[nSeg] "Thermal power per segment"; + Modelica.Blocks.Interfaces.RealInput HGloTil; + + + // ===== Subcomponents ===== + final IDEAS.Fluid.SolarCollectors.BaseClasses.EN12975SolarGain solGaiStc( + redeclare package Medium = Medium, + final nSeg=nSeg, + final incAngDat=per.incAngDat, + final incAngModDat=per.incAngModDat, + final iamDiff=per.IAMDiff, + final eta0=per.eta0, + final use_shaCoe_in=use_shaCoe_in, + final shaCoe=shaCoe, + final A_c=ATot_internal) + "Identifies heat gained from the sun using the ISO 9806:2013 quasi-dynamic standard calculations" + annotation (Placement(transformation(extent={{-20,40},{0,60}}))); + + final IDEAS.Fluid.PVTCollectors.BaseClasses.ISO9806QuasiDynamicHeatLoss heaLosStc( + redeclare package Medium = Medium, + final nSeg=nSeg, + final c1=per.c1, + final c2=per.c2, + final c3=per.c3, + final c4=per.c4, + final c6=per.c6, + final A_c=ATot_internal) + "Calculates the heat lost to the surroundings using the ISO 9806:2013 quasi-dynamic standard calculations" + annotation (Placement(transformation(extent={{-20,10},{0,30}}))); + + final IDEAS.Fluid.PVTCollectors.BaseClasses.ElectricalPVT eleGen( + final nSeg = nSeg, + final A_c = ATot_internal, + final pLossFactor = pLossFactor, + final gamma = per.gamma, + final P_nominal = per.P_nominal, + final A = per.A, + final eta0 = per.eta0, + final tauAlphaEff = tauAlphaEff, + final c1 = per.c1, + final etaEl = per.etaEl) + annotation (Placement(transformation(extent={{-20,-80},{0,-60}}))); + +equation + // Compute effective wind speed on tilted plane + winSpeTil = weaBus.winSpe * sqrt(1 - ( + cos(weaBus.winDir - (azi + Modelica.Constants.pi)) * cos(til) + + sin(weaBus.winDir - (azi + Modelica.Constants.pi)) * sin(til))^2); + + // Compute global irradiance on tilted surface + HGloTil = HDifTilIso.H + HDirTil.H; + + // Compute per-segment thermal power + for i in 1:nSeg loop + qThSeg[i] = (QGai[i].Q_flow + QLos[i].Q_flow) / (ATot_internal / nSeg); + end for; + + // Assign electrical and thermal outputs + pEl = eleGen.pEl; + qTh = sum(QGai.Q_flow + QLos.Q_flow); + + // Validity check + assert(per.c1 > 0, + "In " + getInstanceName() + ": The heat loss coefficient from the EN 12975 ratings data must be strictly positive. Obtained c1 = " + String(per.c1)); + + // ===== Connectors ===== + connect(shaCoe_internal, solGaiStc.shaCoe_in); + connect(HDirTil.inc, solGaiStc.incAng) annotation (Line( + points={{-59,46},{-50,46},{-50,48},{-22,48}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(HDifTilIso.H, solGaiStc.HSkyDifTil) annotation (Line( + points={{-59,80},{-30,80},{-30,58},{-22,58}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(HDirTil.H, solGaiStc.HDirTil) annotation (Line( + points={{-59,50},{-50,50},{-50,52},{-22,52}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(shaCoe_in, solGaiStc.shaCoe_in) annotation (Line( + points={{-120,40},{-40,40},{-40,45},{-22,45}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(solGaiStc.QSol_flow, QGai.Q_flow) annotation (Line( + points={{1,50},{50,50}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(temSen.T, solGaiStc.TFlu) annotation (Line( + points={{-11,-20},{-30,-20},{-30,42},{-22,42}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(heaLosStc.QLos_flow, QLos.Q_flow) + annotation (Line(points={{1,20},{50,20}}, color={0,0,127})); + connect(heaLosStc.TFlu, temSen.T) annotation (Line(points={{-22,14},{-30,14},{ + -30,-20},{-11,-20}}, color={0,0,127})); + connect(weaBus.TDryBul, heaLosStc.TEnv) annotation (Line( + points={{-99.95,80.05},{-100,80.05},{-100,80},{-90,80},{-90,26},{-22,26}}, + color={255,204,51}, + thickness=0.5), Text( + string="%first", + index=-1, + extent={{-6,3},{-6,3}}, + horizontalAlignment=TextAlignment.Right)); + connect(weaBus.HHorIR, heaLosStc.HHorIR) annotation (Line( + points={{-99.95,80.05},{-90,80.05},{-90,20},{-22,20}}, + color={255,204,51}, + thickness=0.5), Text( + string="%first", + index=-1, + extent={{-6,3},{-6,3}}, + horizontalAlignment=TextAlignment.Right)); + connect(temSen.T, eleGen.Tm) annotation (Line(points={{-11,-20},{-30,-20}, {-30,-64},{-22,-64}}, color={0,0,127})); + connect(qThSeg, eleGen.qth); + connect(HGloTil, eleGen.HGloTil); + connect(HGloTil, heaLosStc.HGloTil); + connect(winSpeTil, heaLosStc.winSpePla); + + annotation ( + defaultComponentName = "PvtCol", + + Documentation(info = " +

+ This component models a photovoltaic–thermal (PVT) collector by coupling the ISO 9806 quasi‑dynamic thermal method with an internal electrical model. The model uses only datasheet parameters (no measured calibration data) and has been validated experimentally on unglazed (with and without rear insulation) PVT collectors under a wide range of weather conditions. +

+ +

Submodel References

+ + +

Implementation Notes

+

+ This model supports (unglazed) PVT collectors, discretized into segments to capture temperature gradients. It is compatible with dynamic simulations where irradiance and fluid temperatures vary over time. +

+ +

References

+ + ", +revisions=" + +"), + Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,100}}), + graphics={ + Rectangle(extent={{-84,100},{84,-100}}, lineColor={27,0,55}, fillColor={26,0,55}, fillPattern=FillPattern.Solid), + Line(points={{-100,0},{-76,0},{-76,-90},{66,-90},{66,-60},{-64,-60},{-64,-30},{66,-30},{66,0},{-64,0},{-64,28},{66,28},{66,60},{-64,60},{-64,86},{78,86},{78,0},{98,0},{100,0}}, color={0,128,255}, thickness=1), + Ellipse(extent={{-24,26},{28,-26}}, lineColor={255,255,0}, fillColor={255,255,0}, fillPattern=FillPattern.Solid), + Line(points={{-6,-6},{8,8}}, color={255,255,0}, origin={-24,30}, rotation=90), + Line(points={{-50,0},{-30,0}}, color={255,255,0}), + Line(points={{-36,-40},{-20,-24}}, color={255,255,0}), + Line(points={{-10,0},{10,0}}, color={255,255,0}, origin={2,-40}, rotation=90), + Line(points={{-8,-8},{6,6}}, color={255,255,0}, origin={30,-30}, rotation=90), + Line(points={{32,0},{52,0}}, color={255,255,0}), + Line(points={{-8,-8},{6,6}}, color={255,255,0}, origin={28,32}, rotation=180), + Line(points={{-10,0},{10,0}}, color={255,255,0}, origin={0,40}, rotation=90), + Polygon(points={{72,96},{36,26},{60,34},{48,-24},{88,58},{64,48},{72,96}}, lineColor={0,0,0}, fillColor={0,255,0}, fillPattern=FillPattern.Solid)})); +end PVTQuasiDynamicCollector; diff --git a/IDEAS/Fluid/PvtCollectors/QuasiDynamicPvtCollector.mo b/IDEAS/Fluid/PvtCollectors/QuasiDynamicPvtCollector.mo deleted file mode 100644 index d729bb9ac6..0000000000 --- a/IDEAS/Fluid/PvtCollectors/QuasiDynamicPvtCollector.mo +++ /dev/null @@ -1,209 +0,0 @@ -within IDEAS.Fluid.PvtCollectors; -model QuasiDynamicPvtCollector - "Model of a photovoltaic–thermal (PVT) collector using the ISO 9806:2013 quasi-dynamic thermal method with integrated electrical coupling" - - extends IDEAS.Fluid.PvtCollectors.BaseClasses.PartialPvtCollector - (redeclare IDEAS.Fluid.PvtCollectors.Data.GenericQuasiDynamic per); - - Real windSpeTil "Effective wind speed normal to collector plane"; - - IDEAS.Fluid.SolarCollectors.BaseClasses.EN12975SolarGain solGai( - redeclare package Medium = Medium, - final nSeg=nSeg, - final incAngDat=per.incAngDat, - final incAngModDat=per.incAngModDat, - final iamDiff=per.IAMDiff, - final eta0=per.eta0, - final use_shaCoe_in=use_shaCoe_in, - final shaCoe=shaCoe, - final A_c=ATot_internal) - "Identifies heat gained from the sun using the EN12975 standard calculations" - annotation (Placement(transformation(extent={{-20,40},{0,60}}))); - IDEAS.Fluid.PvtCollectors.BaseClasses.EN12975HeatLoss_QuasiDynamic heaLos( - redeclare package Medium = Medium, - final nSeg=nSeg, - final c1=per.c1, - final c2=per.c2, - final c3=per.c3, - final c4=per.c4, - final c6=per.c6, - final A_c=ATot_internal) - "Calculates the heat lost to the surroundings using the EN12975 standard calculations" - annotation (Placement(transformation(extent={{-20,10},{0,30}}))); - -equation - // Compute plane wind speed (using inherited azi/til and connected weaBus): - windSpeTil = weaBus.winSpe - * sqrt(1 - ( - cos(weaBus.winDir - (azi + Modelica.Constants.pi)) * cos(til) - + sin(weaBus.winDir - (azi + Modelica.Constants.pi)) * sin(til)) - ^2); - heaLos.windSpePlane = windSpeTil; - - // Make sure the model is only used with the EN ratings data, and hence c1 > 0 - assert(per.c1 > 0, - "In " + getInstanceName() + ": The heat loss coefficient from the EN 12975 ratings data must be strictly positive. Obtained c1 = " + String(per.c1)); - connect(shaCoe_internal, solGai.shaCoe_in); - - connect(HDirTil.inc, solGai.incAng) annotation (Line( - points={{-59,46},{-50,46},{-50,48},{-22,48}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(HDifTilIso.H, solGai.HSkyDifTil) annotation (Line( - points={{-59,80},{-30,80},{-30,58},{-22,58}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(HDirTil.H, solGai.HDirTil) annotation (Line( - points={{-59,50},{-50,50},{-50,52},{-22,52}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(shaCoe_in, solGai.shaCoe_in) annotation (Line( - points={{-120,40},{-40,40},{-40,45},{-22,45}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(heaLos.TFlu, temSen.T) annotation (Line( - points={{-22,15.6},{-30,15.6},{-30,-20},{-11,-20}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(heaLos.QLos_flow, QLos.Q_flow) annotation (Line( - points={{1,20},{26,20},{26,20},{50,20}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(solGai.QSol_flow, QGai.Q_flow) annotation (Line( - points={{1,50},{50,50}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(temSen.T, solGai.TFlu) annotation (Line( - points={{-11,-20},{-30,-20},{-30,42},{-22,42}}, - color={0,0,127}, - smooth=Smooth.None)); - connect(heaLos.WeaBus, weaBus) annotation (Line( - points={{-20.4,27.2},{-90,27.2},{-90,80},{-100,80}}, - color={255,204,51}, - thickness=0.5), Text( - string="%second", - index=1, - extent={{-6,3},{-6,3}}, - horizontalAlignment=TextAlignment.Right)); - connect(gGlob.y, heaLos.G) annotation (Line(points={{24,67},{24,34},{-32,34}, - {-32,18.6},{-22,18.6}}, color={0,0,127})); - annotation ( - defaultComponentName="PvtCol", - Documentation(info = " -

- This component models a photovoltaic–thermal (PVT) collector by - coupling the ISO 9806 quasi-dynamic thermal method - with an internal electrical model. The model uses only - datasheet parameters (no measured calibration data). The - electrical output is calculated via a two-node PV–fluid coupling. - The model has been validated experimentally on unglazed (with and without - rear insulation) PVT collectors under a wide range of weather conditions. -

-

References

- - "), - revisions = " - - ", - Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100, - 100}}), - graphics={ - Rectangle( - extent={{-84,100},{84,-100}}, - lineColor={27,0,55}, - fillColor={26,0,55}, - fillPattern=FillPattern.Solid), - Line( - points={{-100,0},{-76,0},{-76,-90},{66,-90},{66,-60},{-64,-60},{-64, - -30},{66,-30},{66,0},{-64,0},{-64,28},{66,28},{66,60},{-64,60},{ - -64,86},{78,86},{78,0},{98,0},{100,0}}, - color={0,128,255}, - thickness=1, - smooth=Smooth.None), - Ellipse( - extent={{-24,26},{28,-26}}, - lineColor={255,255,0}, - fillColor={255,255,0}, - fillPattern=FillPattern.Solid), - Line( - points={{-6,-6},{8,8}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1, - origin={-24,30}, - rotation=90), - Line( - points={{-50,0},{-30,0}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1), - Line( - points={{-36,-40},{-20,-24}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1), - Line( - points={{-10,0},{10,0}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1, - origin={2,-40}, - rotation=90), - Line( - points={{-8,-8},{6,6}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1, - origin={30,-30}, - rotation=90), - Line( - points={{32,0},{52,0}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1), - Line( - points={{-8,-8},{6,6}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1, - origin={28,32}, - rotation=180), - Line( - points={{-10,0},{10,0}}, - color={255,255,0}, - smooth=Smooth.None, - thickness=1, - origin={0,40}, - rotation=90), - Polygon( - points={{72,96},{36,26},{60,34},{48,-24},{88,58},{64,48},{72,96}}, - lineColor={0,0,0}, - fillColor={0,255,0}, - fillPattern=FillPattern.Solid)})); -end QuasiDynamicPvtCollector; diff --git a/IDEAS/Fluid/PvtCollectors/Types/CollectorType.mo b/IDEAS/Fluid/PvtCollectors/Types/CollectorType.mo index ce82b884da..aa1a9bfdff 100644 --- a/IDEAS/Fluid/PvtCollectors/Types/CollectorType.mo +++ b/IDEAS/Fluid/PvtCollectors/Types/CollectorType.mo @@ -1,4 +1,4 @@ -within IDEAS.Fluid.PvtCollectors.Types; +within IDEAS.Fluid.PVTCollectors.Types; type CollectorType = enumeration( Covered "Covered collector", Uncovered "Uncovered collector"); diff --git a/IDEAS/Fluid/PvtCollectors/Types/package.mo b/IDEAS/Fluid/PvtCollectors/Types/package.mo index fde5d5633e..dd7026a2ed 100644 --- a/IDEAS/Fluid/PvtCollectors/Types/package.mo +++ b/IDEAS/Fluid/PvtCollectors/Types/package.mo @@ -1,10 +1,21 @@ -within IDEAS.Fluid.PvtCollectors; -package Types "Package with type definitions used in Pvt collector model" +within IDEAS.Fluid.PVTCollectors; +package Types "Package with type definitions used in PVT collector model" extends Modelica.Icons.TypesPackage; annotation (Documentation(info="

- This package contains type definitions used in Pvt thermal collector models. + This package contains type definitions used in PVT thermal collector models.

+", +revisions=" + ")); end Types; diff --git a/IDEAS/Fluid/PvtCollectors/UsersGuide.mo b/IDEAS/Fluid/PvtCollectors/UsersGuide.mo index 5283629313..96043dbe87 100644 --- a/IDEAS/Fluid/PvtCollectors/UsersGuide.mo +++ b/IDEAS/Fluid/PvtCollectors/UsersGuide.mo @@ -1,76 +1,120 @@ -within IDEAS.Fluid.PvtCollectors; +within IDEAS.Fluid.PVTCollectors; package UsersGuide "User’s Guide" extends Modelica.Icons.Information; annotation(preferredView="info", Documentation(info="

This package contains a model for photovoltaic–thermal (PVT) collectors -based on the ISO 9806:2013 quasi-dynamic thermal procedure (EN 12975) +based on the ISO 9806:2013 quasi-dynamic thermal procedure coupled with an internal electrical submodel. Only the quasi-dynamic approach is directly supported to model the thermal performance.

Model description

+ +
Conversion of other ISO 9806 standards (thermal)
+

+Thermal parameters obtained from other ISO 9806 test procedures, such as the ISO 9806:2013 unglazed test or the ISO 9806:2017 quasi-dynamic method, +can be converted into the thermal parameter set required by this model (c₁ to c₆, η₀, and Kd) +using the procedure detailed in +SKN-N0474R0: Thermal Performance Parameter Conversion to ISO 9806-2017. +

+

+For the thermal part:

- -

1. Conversion of other ISO 9806 standards (thermal)

-

-Thermal parameters obtained from other ISO 9806 test procedures, such as -the ISO 9806:2013 unglazed test or the ISO 9806:2017 quasi-dynamic method, can be -converted into the c1…c6, η0, Kd -thermal parameter set required by this model using the procedure detailed in - -SKN-N0474R0: Thermal Performance Parameter Conversion to ISO 9806-2017. -

-

-Because QuasiDynamicPvtCollector extends -IDEAS.Fluid.SolarCollectors.BaseClasses.PartialSolarCollector and uses -similar solar gain and heat loss blocks as the EN 12975 solar collector model -(IDEAS.Fluid.SolarCollectors.EN12975), it is also advisable to consult -the SolarCollectors User’s Guide -( -IDEAS.Fluid.SolarCollectors.UsersGuide) for deeper insights into thermal performance data -and parameter usage.

-

2. Electrical performance and losses

+ +
Electrical performance and losses

The electrical submodel follows the PVWatts v5 approach (Dobos, 2014), with module parameters from the datasheet plus an overall system loss factor -pLossFactor. NREL’s PVWatts reports a typical total loss of -14 %, distributed as: +pLossFactor. NREL’s PVWatts reports a total electrical power loss of +14%, which are a result of the following loss mechanism:

- - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Loss mechanismDefault value
Soiling2 %
Shading3 %
Mismatch2 %
Wiring2 %
Connections0.5 %
Light-induced degradation1.5 %
Nameplate rating1 %
Availability3 %
Total14 %
Electrical power loss mechanismDefault value
Soiling2 %
Shading3 %
Mismatch2 %
Wiring2 %
Connections0.5 %
Light‑induced degradation1.5 %
Nameplate rating1 %
Availability3 %
Total14 %
+

For well-maintained, unshaded modules, experimental validation (Meertens et al., 2025) -found that using pLossFactor = 7 % gives excellent agreement with -measured electrical output. Users may adjust pLossFactor to account for -site-specific soiling or shading effects. +found that using pLossFactor = 9 % gives excellent agreement with +measured electrical output. For PVT collectors with high positive tolerance on the +electrical output, this system loss factor can even be reduced more. +Users may adjust pLossFactor to account for site-specific soiling or shading effects. +

+ +

+For the electrical part: +

-

3. Electrical–thermal coupling

+
Electrical–thermal coupling

-The internal heat transfer coefficient UAbsFluid is calculated from datasheet parameters: + The internal heat transfer coefficient UAbsFluid is approximately calculated from datasheet parameters:

+
-
UAbsFluid =
+
UAbsFluid
@@ -85,36 +129,55 @@ The internal heat transfer coefficient UAbsFluid is calculated from
+ -

This approach removes the need for a hidden fit parameter: both thermal and electrical coupling coefficients derive solely from publicly available datasheet values.

-

References

+", +revisions=" + ")); end UsersGuide; diff --git a/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/ISO9806QuasiDynamicHeatLossValidation.mo b/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/ISO9806QuasiDynamicHeatLossValidation.mo new file mode 100644 index 0000000000..8223a35f0e --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/ISO9806QuasiDynamicHeatLossValidation.mo @@ -0,0 +1,64 @@ +within IDEAS.Fluid.PVTCollectors.Validation.BaseClasses; +block ISO9806QuasiDynamicHeatLossValidation + "Validation variant with term‑by‑term breakdown of quasi‑dynamic heat loss" + + extends IDEAS.Fluid.PVTCollectors.BaseClasses.ISO9806QuasiDynamicHeatLoss; + + // —— Diagnostic internal variables —— + Real c1_c2_term(unit="W") + "Contribution from c1–c2 (steady‑state) term"; + Real c3_term(unit="W") + "Contribution from wind‑speed dependence (c3)"; + Real c4_term(unit="W") + "Contribution from sky long‑wave (c4)"; + Real c6_term(unit="W") + "Contribution from wind–irradiance coupling (c6)"; + Real EL_term(unit="W/m2") + "Sky long‑wave irradiance difference (HHorIR – σ·TEnv⁴)"; + + // —— Cumulative sums —— + Real pvt_st_st(unit="W") "Steady‑state loss (c1–c2)"; + Real pvt_c3( unit="W") "Steady‑state + c3"; + Real pvt_c4( unit="W") "Steady‑state + c3 + c4"; + Real pvt_c6( unit="W") "Total quasi‑dynamic loss"; + +equation + // term-by-term breakdown + c1_c2_term = sum(A_c/nSeg * { dT[i]*(c1 - c2*dT[i]) for i in 1:nSeg}); + c3_term = sum(A_c/nSeg * { dT[i]*c3*winSpePla for i in 1:nSeg}); + c4_term = sum(A_c/nSeg * { c4*(HHorIR - sigma*TEnv^4) for i in 1:nSeg}); + c6_term = sum(A_c/nSeg * { -c6*winSpePla*HGloTil for i in 1:nSeg}); + EL_term = HHorIR - sigma*TEnv^4; + + // cumulative contributions + pvt_st_st = c1_c2_term; + pvt_c3 = pvt_st_st + c3_term; + pvt_c4 = pvt_c3 + c4_term; + pvt_c6 = pvt_c4 + c6_term; + + annotation ( + defaultComponentName="heaLosStcVal", + Documentation(info = " + +

+ Extends the standard quasi‑dynamic heat‑loss model + (IDEAS.Fluid.PVTCollectors.BaseClasses.ISO9806QuasiDynamicHeatLoss). + For validation purposes, this block adds: +

+ + +", revisions=" + +")); +end ISO9806QuasiDynamicHeatLossValidation; diff --git a/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/package.mo b/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/package.mo new file mode 100644 index 0000000000..188d1fb513 --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/package.mo @@ -0,0 +1,3 @@ +within IDEAS.Fluid.PVTCollectors.Validation; +package BaseClasses +end BaseClasses; diff --git a/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/package.order b/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/package.order new file mode 100644 index 0000000000..ce42af1e2d --- /dev/null +++ b/IDEAS/Fluid/PvtCollectors/Validation/BaseClasses/package.order @@ -0,0 +1 @@ +ISO9806QuasiDynamicHeatLossValidation diff --git a/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/EN12975HeatLossValidationPVT1.mo b/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/EN12975HeatLossValidationPVT1.mo deleted file mode 100644 index ab1baee383..0000000000 --- a/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/EN12975HeatLossValidationPVT1.mo +++ /dev/null @@ -1,62 +0,0 @@ -within IDEAS.Fluid.PvtCollectors.Validation.PVT1.BaseClasses; -block EN12975HeatLossValidationPVT1 - extends IDEAS.Fluid.PvtCollectors.BaseClasses.EN12975HeatLoss_SteadyState - ( QLos_internal=A_c/nSeg*{dT[i] * (c1 - c2 * dT[i] + c3*u) + c4*(E_L - sigma*TEnv^4) - - c6*u*G for i in 1:nSeg}); - - // Constants - parameter Real c3(final unit = "J/(m3.K)", final min=0) "a3 from ratings data"; - parameter Real c4(final unit = "", final min=0) "c4 from ratings data"; - parameter Real c6(final unit = "J/(m3.K)", final min=0) "c6 from ratings data"; - parameter Real sigma = 5.67e-8 "Stefan-Boltzmann constant [W/m²K^4]"; - - // Inputs - Modelica.Blocks.Interfaces.RealInput u( - quantity="Windspeed", - unit="m/s", - displayUnit="m/s") "windspeed of surrounding air" - annotation (Placement(transformation(extent={{-142,0},{-100,42}}), - iconTransformation(extent={{-142,0},{-100,42}}))); - Modelica.Blocks.Interfaces.RealInput E_L( - quantity="long-wave solar irradiance", - unit="W/m2", - displayUnit="W/m2") "Long-wave solar irradiance [W/m2]" annotation (Placement( - transformation(extent={{-21,-21},{21,21}}, - rotation=0, - origin={-121,-99}), iconTransformation( - extent={{-142,-120},{-100,-78}}))); - - Modelica.Blocks.Interfaces.RealInput G( - quantity="Global solar irradiance", - unit="W/m2", - displayUnit="W/m2") "global solar irradiance [W/m2]" annotation (Placement( - transformation(extent={{-21,-21},{21,21}}, - rotation=0, - origin={-121,-21}), iconTransformation( - extent={{-140,-42},{-98,0}}))); - - // Internal variables to be visible in simulation results - Real c1_c2_term(unit="W"); - Real c3_term(unit="W"); - Real c4_term(unit="W"); - Real c6_term(unit="W"); - Real EL_term( unit="W/m2"); - - Real pvt_st_st(unit="W"); - Real pvt_c3(unit="W"); - Real pvt_c4(unit="W"); - Real pvt_c6(unit="W"); - - // Equations for terms -equation - c1_c2_term = sum(A_c/nSeg*{dT[i]*(c1 - c2*dT[i]) for i in 1:nSeg}); - c3_term = sum(A_c/nSeg*{dT[i]*(c3*u) for i in 1:nSeg}); - c4_term = sum(A_c/nSeg*{c4*(E_L - sigma*TEnv^4) for i in 1:nSeg}); - EL_term = E_L - sigma*TEnv^4; - c6_term = sum(A_c/nSeg*{(-1)* c6*u*G for i in 1:nSeg}); - pvt_st_st = c1_c2_term; - pvt_c3 = c1_c2_term + c3_term; - pvt_c4 = c1_c2_term + c3_term + c4_term; - pvt_c6 = c1_c2_term + c3_term + c4_term + c6_term; - -end EN12975HeatLossValidationPVT1; diff --git a/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/LongWaveRadiation.mo b/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/LongWaveRadiation.mo index 658bc0e1b3..3e1578eac7 100644 --- a/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/LongWaveRadiation.mo +++ b/IDEAS/Fluid/PvtCollectors/Validation/PVT1/BaseClasses/LongWaveRadiation.mo @@ -1,4 +1,4 @@ -within IDEAS.Fluid.PvtCollectors.Validation.PVT1.BaseClasses; +within IDEAS.Fluid.PVTCollectors.Validation.PVT1.BaseClasses; model LongWaveRadiation extends Modelica.Blocks.Icons.Block; @@ -70,4 +70,45 @@ equation // Calculate Longwave Radiation (lonRad) using Tview and the Stefan-Boltzmann Law lonRad = sigma*Tamb^4*((epsSky*(1 + cos(tiltAngle)) / 2) + (epsGro*(1 - cos(tiltAngle)) / 2)); +annotation ( + defaultComponentName="LongWaveRad", + Documentation(info = " +

+ Computes longwave radiation exchange between the sky and a tilted surface using ambient meteorological inputs. + The model estimates sky emissivity based on the dew point temperature derived from ambient temperature and relative humidity, + following Buck's equation. It then applies the Stefan–Boltzmann law to calculate the net longwave radiation on a tilted surface, + accounting for both sky and ground contributions. +

+ +

Implementation Notes

+

+ This model is used in the validation of unglazed photovoltaic–thermal (PVT) collectors + ( IDEAS.Fluid.PVTCollectors.Validation.PVT1.PVTQuasiDynamicCollectorValidation) + where direct longwave irradiance measurements are unreliable or unavailable. It uses a fixed tilt angle of 45° and assumes a ground emissivity of 0.95. + The clear-sky emissivity is calculated using an empirical correlation based on the dew point temperature. + The model is particularly useful in dynamic simulations where longwave radiation must be estimated from standard meteorological data. +

+ +

References

+