solarCalculator.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "solarCalculator.H"
29 #include "Time.H"
30 #include "unitConversion.H"
31 #include "constants.H"
32 
33 using namespace Foam::constant;
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(solarCalculator, 0);
40 }
41 
42 
43 const Foam::Enum
44 <
46 >
48 ({
49  { sunDirModel::mSunDirConstant, "sunDirConstant" },
50  { sunDirModel::mSunDirTracking, "sunDirTracking" },
51 });
52 
53 
54 const Foam::Enum
55 <
57 >
59 ({
60  { sunLModel::mSunLoadConstant, "sunLoadConstant" },
61  {
62  sunLModel::mSunLoadFairWeatherConditions,
63  "sunLoadFairWeatherConditions"
64  },
65  { sunLModel::mSunLoadTheoreticalMaximum, "sunLoadTheoreticalMaximum" },
66 });
67 
68 
69 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
70 
71 void Foam::solarCalculator::calculateBetaTheta()
72 {
73  scalar runTime = 0.0;
74  switch (sunDirectionModel_)
75  {
76  case mSunDirTracking:
77  {
78  runTime = mesh_.time().value();
79  break;
80  }
81  case mSunDirConstant:
82  {
83  break;
84  }
85  }
86 
87  scalar LSM = 15.0*(dict_.get<scalar>("localStandardMeridian"));
88 
89  scalar D = dict_.get<scalar>("startDay") + runTime/86400.0;
90  scalar M = 6.24004 + 0.0172*D;
91  scalar EOT = -7.659*sin(M) + 9.863*sin(2*M + 3.5932);
92 
93  dict_.readEntry("startTime", startTime_);
94 
95  scalar LST = startTime_ + runTime/3600.0;
96 
97  scalar LON = dict_.get<scalar>("longitude");
98 
99  scalar AST = LST + EOT/60.0 + (LON - LSM)/15;
100 
101  scalar delta = 23.45*sin(degToRad((360*(284 + D))/365));
102 
103  scalar H = degToRad(15*(AST - 12));
104 
105  scalar L = degToRad(dict_.get<scalar>("latitude"));
106 
107  scalar deltaRad = degToRad(delta);
108  beta_ = max(asin(cos(L)*cos(deltaRad)*cos(H) + sin(L)*sin(deltaRad)), 1e-3);
109  theta_ = acos((sin(beta_)*sin(L) - sin(deltaRad))/(cos(beta_)*cos(L)));
110 
111  // theta is the angle between the SOUTH axis and the Sun
112  // If the hour angle is lower than zero (morning) the Sun is positioned
113  // on the East side.
114  if (H < 0)
115  {
116  theta_ += 2*(constant::mathematical::pi - theta_);
117  }
118 
119  DebugInfo
120  << tab << "altitude : " << radToDeg(beta_) << nl
121  << tab << "azimuth : " << radToDeg(theta_) << endl;
122 }
123 
124 
125 void Foam::solarCalculator::calculateSunDirection()
126 {
127  gridUp_ = normalised(dict_.get<vector>("gridUp"));
128  eastDir_ = normalised(dict_.get<vector>("gridEast"));
129 
130  coord_.reset
131  (
132  new coordinateSystem("grid", Zero, gridUp_, eastDir_)
133  );
134 
135  // Assuming 'z' vertical, 'y' North and 'x' East
136  direction_.z() = -sin(beta_);
137  direction_.y() = cos(beta_)*cos(theta_); // South axis
138  direction_.x() = cos(beta_)*sin(theta_); // West axis
139 
140  direction_.normalise();
141 
142  DebugInfo
143  << "Sun direction in absolute coordinates : " << direction_ <<endl;
144 
145  // Transform to actual coordinate system
146  direction_ = coord_->transform(direction_);
147 
148  DebugInfo
149  << "Sun direction in the Grid coordinates : " << direction_ <<endl;
150 }
151 
152 
153 void Foam::solarCalculator::init()
154 {
155  switch (sunDirectionModel_)
156  {
157  case mSunDirConstant:
158  {
159  if (dict_.readIfPresent("sunDirection", direction_))
160  {
161  direction_.normalise();
162  }
163  else
164  {
165  calculateBetaTheta();
166  calculateSunDirection();
167  }
168 
169  break;
170  }
171  case mSunDirTracking:
172  {
173  if (word(mesh_.ddtScheme("default")) == "steadyState")
174  {
176  << " Sun direction model can not be sunDirtracking if the "
177  << " case is steady " << nl << exit(FatalError);
178  }
179 
180  dict_.readEntry
181  (
182  "sunTrackingUpdateInterval",
183  sunTrackingUpdateInterval_
184  );
185 
186  calculateBetaTheta();
187  calculateSunDirection();
188  break;
189  }
190  }
191 
192  switch (sunLoadModel_)
193  {
194  case mSunLoadConstant:
195  {
196  dict_.readEntry("directSolarRad", directSolarRad_);
197  dict_.readEntry("diffuseSolarRad", diffuseSolarRad_);
198  break;
199  }
200  case mSunLoadFairWeatherConditions:
201  {
202  dict_.readIfPresent
203  (
204  "skyCloudCoverFraction",
205  skyCloudCoverFraction_
206  );
207 
208  dict_.readEntry("A", A_);
209  dict_.readEntry("B", B_);
210 
211  if (!dict_.readIfPresent("beta", beta_))
212  {
213  calculateBetaTheta();
214  }
215 
216  directSolarRad_ =
217  (1.0 - 0.75*pow(skyCloudCoverFraction_, 3.0))
218  * A_/exp(B_/sin(beta_));
219 
220  dict_.readEntry("groundReflectivity", groundReflectivity_);
221  break;
222  }
223  case mSunLoadTheoreticalMaximum:
224  {
225  dict_.readEntry("Setrn", Setrn_);
226  dict_.readEntry("SunPrime", SunPrime_);
227  directSolarRad_ = Setrn_*SunPrime_;
228 
229  dict_.readEntry("groundReflectivity", groundReflectivity_);
230  break;
231  }
232  }
233 }
234 
235 
236 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
237 
238 Foam::solarCalculator::solarCalculator
239 (
240  const dictionary& dict,
241  const fvMesh& mesh
242 )
243 :
244  mesh_(mesh),
245  dict_(dict),
246  direction_(Zero),
247  directSolarRad_(0.0),
248  diffuseSolarRad_(0.0),
249  groundReflectivity_(0.0),
250  A_(0.0),
251  B_(0.0),
252  beta_(0.0),
253  theta_(0.0),
254  skyCloudCoverFraction_(0.0),
255  Setrn_(0.0),
256  SunPrime_(0.0),
257  C_(dict.get<scalar>("C")),
258  sunDirectionModel_
259  (
260  sunDirectionModelTypeNames_.get("sunDirectionModel", dict)
261  ),
262  sunLoadModel_(sunLoadModelTypeNames_.get("sunLoadModel", dict)),
263  coord_()
264 {
265  init();
266 }
267 
268 
269 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
270 
272 {
273  switch (sunDirectionModel_)
274  {
275  case mSunDirConstant:
276  {
277  break;
278  }
279  case mSunDirTracking:
280  {
281  calculateBetaTheta();
282  calculateSunDirection();
283  directSolarRad_ = A_/exp(B_/sin(max(beta_, ROOTVSMALL)));
284  break;
285  }
286  }
287 }
288 
289 
290 // ************************************************************************* //
runTime
engineTime & runTime
Definition: createEngineTime.H:13
L
const vector L(dict.get< vector >("L"))
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::constant
Different types of constants.
Definition: atomicConstants.C:38
Foam::sin
dimensionedScalar sin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:264
H
volScalarField H(IOobject("H", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimLength, Zero))
unitConversion.H
Unit conversion functions.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::exp
dimensionedScalar exp(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:261
Foam::solarCalculator::sunLModel
sunLModel
Direct sun load models.
Definition: solarCalculator.H:119
init
mesh init(true)
delta
scalar delta
Definition: LISASMDCalcMethod2.H:8
Foam::radToDeg
constexpr scalar radToDeg(const scalar rad) noexcept
Conversion from radians to degrees.
Definition: unitConversion.H:54
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:83
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
constants.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:483
Time.H
Foam::solarCalculator::correctSunDirection
void correctSunDirection()
Recalculate.
Definition: solarCalculator.C:271
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:359
Foam::tab
constexpr char tab
Definition: Ostream.H:384
Foam::constant::mathematical::pi
constexpr scalar pi(M_PI)
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::solarCalculator::sunDirectionModelTypeNames_
static const Enum< sunDirModel > sunDirectionModelTypeNames_
Sun direction models.
Definition: solarCalculator.H:130
Foam::acos
dimensionedScalar acos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:268
M
#define M(I)
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
solarCalculator.H
D
const dimensionedScalar & D
Definition: solveBulkSurfactant.H:4
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::solarCalculator::sunDirModel
sunDirModel
Sun direction models.
Definition: solarCalculator.H:112
Foam::solarCalculator::sunLoadModelTypeNames_
static const Enum< sunLModel > sunLoadModelTypeNames_
Sun load models.
Definition: solarCalculator.H:133
Foam::asin
dimensionedScalar asin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:267
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265