1.3.49
 
Loading...
Searching...
No Matches
BoundaryLayerConductanceModel.cpp
Go to the documentation of this file.
1
17
18using namespace helios;
19
21
22 wind_speed_default = 1.f;
23
24 air_temperature_default = 293.f;
25
26 surface_temperature_default = 303.f;
27
28 message_flag = true; // print messages to screen by default
29
30 // Copy pointer to the context
31 context = __context;
32}
33
35 message_flag = true;
36}
37
39 message_flag = false;
40}
41
43 std::vector<uint> UUIDs = context->getAllUUIDs();
44 setBoundaryLayerModel(UUIDs, gH_model);
45}
46
47void BLConductanceModel::setBoundaryLayerModel(uint UUID, const char *gH_model) {
48 std::vector<uint> UUIDs{UUID};
49 setBoundaryLayerModel(UUIDs, gH_model);
50}
51
52void BLConductanceModel::setBoundaryLayerModel(const std::vector<uint> &UUIDs, const char *gH_model) {
53
54 uint model = 0;
55
56 if (strcmp(gH_model, "Pohlhausen") == 0 || strcmp(gH_model, "Polhausen") == 0) {
57 model = 0;
58 } else if (strcmp(gH_model, "InclinedPlate") == 0) {
59 model = 1;
60 } else if (strcmp(gH_model, "Sphere") == 0) {
61 model = 2;
62 } else if (strcmp(gH_model, "Ground") == 0) {
63 model = 3;
64 } else {
65 std::cerr << "WARNING (EnergyBalanceModel::setBoundaryLayerModel): Boundary-layer conductance model " << gH_model << " is unknown. Skipping this function call.." << std::endl;
66 return;
67 }
68
69 for (uint UUID: UUIDs) {
70 boundarylayer_model[UUID] = model;
71 }
72}
73
75
76 run(context->getAllUUIDs());
77}
78
79void BLConductanceModel::run(const std::vector<uint> &UUIDs) {
80
81 for (uint UUID: UUIDs) {
82
83 float U;
84 if (context->doesPrimitiveDataExist(UUID, "wind_speed")) {
85 context->getPrimitiveData(UUID, "wind_speed", U);
86 } else {
87 U = wind_speed_default;
88 }
89
90 float Ta;
91 if (context->doesPrimitiveDataExist(UUID, "air_temperature")) {
92 context->getPrimitiveData(UUID, "air_temperature", Ta);
93 } else {
94 Ta = air_temperature_default;
95 }
96
97 float T;
98 if (context->doesPrimitiveDataExist(UUID, "temperature")) {
99 context->getPrimitiveData(UUID, "temperature", T);
100 } else {
101 T = surface_temperature_default;
102 }
103
104 float L;
105 if (context->doesPrimitiveDataExist(UUID, "object_length")) {
106 context->getPrimitiveData(UUID, "object_length", L);
107 if (L == 0) {
108 L = sqrt(context->getPrimitiveArea(UUID));
109 }
110 } else if (context->getPrimitiveParentObjectID(UUID) > 0) {
111 uint objID = context->getPrimitiveParentObjectID(UUID);
112 L = sqrt(context->getObjectArea(objID));
113 } else {
114 L = sqrt(context->getPrimitiveArea(UUID));
115 }
116
117 // Number of primitive faces
118 char Nsides = 2; // default is 2
119 if (context->doesPrimitiveDataExist(UUID, "twosided_flag") && context->getPrimitiveDataType("twosided_flag") == HELIOS_TYPE_UINT) {
120 uint flag;
121 context->getPrimitiveData(UUID, "twosided_flag", flag);
122 if (flag == 0) {
123 Nsides = 1;
124 }
125 }
126
127 vec3 norm = context->getPrimitiveNormal(UUID);
128 float inclination = cart2sphere(norm).zenith;
129
130 float gH = calculateBoundaryLayerConductance(boundarylayer_model[UUID], U, L, Nsides, inclination, T, Ta);
131
132 context->setPrimitiveData(UUID, "boundarylayer_conductance", gH);
133 }
134}
135
136float BLConductanceModel::calculateBoundaryLayerConductance(uint gH_model, float U, float L, char Nsides, float inclination, float TL, float Ta) {
137
138
139 assert(gH_model < 4);
140
141 float gH = 0;
142
143 if (L == 0) {
144 return 0;
145 }
146
147 if (gH_model == 0) { // Pohlhausen equation
148 // This comes from the correlation by Pohlhausen - see Eq. XX of Campbell and Norman (1998). It assumes a flat plate parallel to the direction of the flow, which extends infinitely in the cross-stream direction and "L" in the streamwise
149 // direction. It also assumes that the air is at standard temperature and pressure, and flow is laminar, forced convection.
150
151 gH = 0.135f * sqrt(U / L) * float(Nsides);
152
153 } else if (gH_model == 1) { // Inclined Plate
154
155 float Pr = 0.7f; // air Prandtl number
156
157 float nu = 1.568e-5; // air viscosity (m^2/sec)
158 float alpha = nu / Pr; // air diffusivity (m^2/sec)
159
160 float Re = U * L / nu;
161
162 float Gr = 9.81f * fabs(TL - Ta) * std::pow(L, 3) / ((Ta) *nu * nu);
163
164 // For zero or very low wind speed, revert to pure free convection
165 if (U <= 1e-6f || Re <= 1e-6f) {
166 // Pure natural convection correlation for inclined plates
167 float Nu_free;
168 if (inclination < 75.f * M_PI / 180.f || inclination > 105.f * M_PI / 180.f) {
169 // Nearly horizontal plates - use horizontal plate correlation
170 Nu_free = 0.54f * std::pow(Gr * fabs(cos(inclination)), 0.25f);
171 } else {
172 // Nearly vertical plates - use vertical plate correlation
173 Nu_free = 0.59f * std::pow(Gr, 0.25f);
174 }
175 gH = Nu_free * (alpha / L);
176 return gH;
177 }
178
179 float F1 = 0.399f * std::pow(Pr, 1.f / 3.f) * pow(1.f + pow(0.0468f / Pr, 2.f / 3.f), -0.25f);
180 float F2 = 0.75f * std::pow(Pr, 0.5f) * pow(2.5f * (1.f + 2.f * pow(Pr, 0.5f) + 2.f * Pr), -0.25f);
181
182 // direction of free convection
183 float free_direction;
184 if (TL >= Ta) {
185 free_direction = 1;
186 } else {
187 free_direction = -1;
188 }
189
190 // free_direction=1;
191
192 if (inclination < 75.f * M_PI / 180.f || inclination > 105.f * M_PI / 180.f) {
193
194 gH = 41.4f * alpha / L * 2.f * F1 * sqrtf(Re) * std::pow(1.f + free_direction * std::pow(2.f * F2 * std::pow(Gr * fabs(cos(inclination)) / (Re * Re), 0.25f) / (3.f * F1), 3), 1.f / 3.f);
195
196 } else {
197
198 float C = 0.07f * sqrtf(fabs(cos(inclination)));
199 float F3 = std::pow(Pr, 0.5f) * std::pow(0.25f + 1.6f * std::pow(Pr, 0.5f), -1.f) * std::pow(Pr / 5.f, 1.f / 5.f + C);
200
201 gH = 41.4f * alpha / L * 2.f * F1 * sqrtf(Re) * std::pow(1.f + free_direction * std::pow((F3 * pow(Gr * pow(Re, -5.f / 2.f), 1.f / 5.f) * std::pow(Gr, C)) / (6.f * (1.f / 5.f + C) * F1), 3.f), 1.f / 3.f);
202 }
203
204 } else if (gH_model == 2) { // Sphere
205
206 // Laminar flow around a sphere (L is sphere diameter). From Eq. 4 of Smart and Sinclair (1976).
207
208 float Pr = 0.7f; // air Prandtl number
209 float nu = 1.568e-5; // air viscosity (m^2/sec)
210 float ka = 0.024; // air thermal conductivity (W/m-K)
211 float cp = 29.25; // air heat capacity (J/mol-K)
212
213 float Re = U * L / nu;
214
215 gH = (ka / cp) / L * (2.0 + 0.6 * sqrtf(Re) * pow(Pr, 1.f / 3.f));
216
217 } else if (gH_model == 3) { // Ground
218 // From Eq. A17 of Kustas and Norman (1999). For the soil-air interface.
219
220 gH = 0.004f + 0.012f * U; // units in (m^3 air)/(m^2-sec.)
221
222 // assuming standard temperature and pressure, (m^3 air)*(1.2041 kg/m^3)/(0.02897 kg/mol) = 41.56 (mol air)/(m^2-sec.)
223
224 gH = gH * 41.56f;
225 }
226
227 return gH;
228}