49 { sunDirModel::mSunDirConstant,
"constant" },
50 { sunDirModel::mSunDirTracking,
"tracking" },
53 { sunDirModel::mSunDirConstant,
"sunDirConstant" },
54 { sunDirModel::mSunDirTracking,
"sunDirTracking" }
64 { sunLModel::mSunLoadConstant,
"constant" },
65 { sunLModel::mSunLoadTimeDependent,
"timeDependent" },
66 { sunLModel::mSunLoadFairWeatherConditions,
"fairWeather" },
67 { sunLModel::mSunLoadTheoreticalMaximum,
"theoreticalMaximum" },
70 { sunLModel::mSunLoadConstant,
"sunLoadConstant" },
72 sunLModel::mSunLoadFairWeatherConditions,
73 "sunLoadFairWeatherConditions" 75 { sunLModel::mSunLoadTheoreticalMaximum,
"sunLoadTheoreticalMaximum" }
81 void Foam::solarCalculator::calculateBetaTheta()
85 if (sunDirectionModel_ == mSunDirTracking)
90 const scalar LSM = 15.0*(dict_.get<scalar>(
"localStandardMeridian"));
92 const scalar
D = dict_.get<scalar>(
"startDay") +
runTime/86400.0;
93 const scalar
M = 6.24004 + 0.0172*
D;
94 const scalar EOT = -7.659*
sin(
M) + 9.863*
sin(2*
M + 3.5932);
96 dict_.readEntry(
"startTime", startTime_);
98 const scalar LST = startTime_ +
runTime/3600.0;
100 const scalar LON = dict_.get<scalar>(
"longitude");
102 const scalar AST = LST + EOT/60.0 + (LON - LSM)/15;
106 const scalar
H =
degToRad(15*(AST - 12));
108 const scalar
L =
degToRad(dict_.get<scalar>(
"latitude"));
128 void Foam::solarCalculator::calculateSunDirection()
135 new coordinateSystem(
"grid",
Zero, gridUp_, eastDir_)
139 direction_.z() = -
sin(beta_);
140 direction_.y() =
cos(beta_)*
cos(theta_);
141 direction_.x() =
cos(beta_)*
sin(theta_);
143 direction_.normalise();
146 <<
"Sun direction in absolute coordinates : " << direction_ <<
endl;
149 direction_ = coord_->transform(direction_);
152 <<
"Sun direction in the Grid coordinates : " << direction_ <<
endl;
156 void Foam::solarCalculator::initialise()
158 switch (sunDirectionModel_)
160 case mSunDirConstant:
162 if (dict_.readIfPresent(
"sunDirection", direction_))
164 direction_.normalise();
168 calculateBetaTheta();
169 calculateSunDirection();
173 case mSunDirTracking:
175 if (word(mesh_.ddtScheme(
"default")) ==
"steadyState")
178 <<
" Sun direction model can not be sunDirtracking if the " 184 "sunTrackingUpdateInterval",
185 sunTrackingUpdateInterval_
188 calculateBetaTheta();
189 calculateSunDirection();
194 switch (sunLoadModel_)
196 case mSunLoadConstant:
198 dict_.readEntry(
"directSolarRad", directSolarRad_);
199 dict_.readEntry(
"diffuseSolarRad", diffuseSolarRad_);
202 case mSunLoadTimeDependent:
204 directSolarRads_.reset
206 Function1<scalar>::New
214 diffuseSolarRads_.reset
216 Function1<scalar>::New
225 directSolarRads_->value(mesh_.time().timeOutputValue());
227 diffuseSolarRads_->value(mesh_.time().timeOutputValue());
230 case mSunLoadFairWeatherConditions:
234 "skyCloudCoverFraction",
235 skyCloudCoverFraction_
238 dict_.readEntry(
"A", A_);
239 dict_.readEntry(
"B", B_);
240 dict_.readEntry(
"C", C_);
241 dict_.readEntry(
"groundReflectivity", groundReflectivity_);
242 if (!dict_.readIfPresent(
"beta", beta_))
244 calculateBetaTheta();
248 (1.0 - 0.75*
pow(skyCloudCoverFraction_, 3.0))
252 case mSunLoadTheoreticalMaximum:
254 dict_.readEntry(
"Setrn", Setrn_);
255 dict_.readEntry(
"SunPrime", SunPrime_);
256 dict_.readEntry(
"groundReflectivity", groundReflectivity_);
257 dict_.readEntry(
"C", C_);
259 directSolarRad_ = Setrn_*SunPrime_;
268 Foam::solarCalculator::solarCalculator
270 const dictionary&
dict,
278 sunDirectionModelTypeNames_.
get(
"sunDirectionModel",
dict)
280 sunLoadModel_(sunLModelTypeNames_.
get(
"sunLoadModel",
dict)),
282 sunTrackingUpdateInterval_(0),
291 skyCloudCoverFraction_(0),
292 groundReflectivity_(0),
309 if (sunDirectionModel_ == mSunDirTracking)
311 calculateBetaTheta();
312 calculateSunDirection();
313 directSolarRad_ = A_/
exp(B_/
sin(
max(beta_, ROOTVSMALL)));
320 if (sunLoadModel_ == mSunLoadTimeDependent)
322 directSolarRad_ = directSolarRads_->value(mesh_.time().value());
329 if (sunLoadModel_ == mSunLoadTimeDependent)
331 diffuseSolarRad_ = diffuseSolarRads_->value(mesh_.time().value());
342 auto& load = tload.ref();
346 const scalar cosEpsilon(gridUp_ & -
n[facei]);
350 const scalar cosTheta(direction_ & -
n[facei]);
353 if (cosEpsilon == 0.0)
360 Y = 0.55+0.437*cosTheta + 0.313*
sqr(cosTheta);
367 Ed = C_*
Y*directSolarRad_;
375 * 0.5*(1.0 + cosEpsilon);
382 * groundReflectivity_
383 * 0.5*(1.0 - cosEpsilon);
385 load[facei] = Ed + Er;
Different types of constants.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
sunLModel
Options for the Sun load models.
dimensionedScalar acos(const dimensionedScalar &ds)
void correctDiffuseSolarRad()
Correct diffuse solar irradiation.
static const Enum< sunDirModel > sunDirectionModelTypeNames_
Names for sunDirModel.
errorManipArg< error, int > exit(error &err, const int errNo=1)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
const vector L(dict.get< vector >("L"))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Unit conversion functions.
constexpr char nl
The newline '\n' character (0x0a)
static const Enum< sunLModel > sunLModelTypeNames_
Names for sunLModel.
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr char tab
The tab '\t' character(0x09)
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
dimensionedScalar asin(const dimensionedScalar &ds)
#define forAll(list, i)
Loop across all elements in list.
void correctDirectSolarRad()
Correct direct solar irradiation.
const dimensionedScalar e
Elementary charge.
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar exp(const dimensionedScalar &ds)
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
constexpr scalar pi(M_PI)
sunDirModel
Options for the Sun direction models.
#define DebugInfo
Report an information message using Foam::Info.
dimensionedScalar sin(const dimensionedScalar &ds)
defineTypeNameAndDebug(combustionModel, 0)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
scalar & diffuseSolarRad()
Return non-const access to the diffuse solar irradiation.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
constexpr scalar radToDeg(const scalar rad) noexcept
Conversion from radians to degrees.
PtrList< volScalarField > & Y
Field< vector > vectorField
Specialisation of Field<T> for vector.
const dimensionedScalar & D
A class for managing temporary objects.
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
volScalarField H(IOobject("H", runTime.timeName(), mesh.thisDb(), IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimLength, Zero))
void correctSunDirection()
Correct the Sun direction.
static constexpr const zero Zero
Global zero (0)