HydroFemPhysics
The GeMA Hydraulic FEM Physics Plugin
Loading...
Searching...
No Matches
gmpMaterialPipeFlow.h
Go to the documentation of this file.
1/************************************************************************
2**
3** Copyright (C) 2014 by Carlos Augusto Teixera Mendes
4** All rights reserved.
5**
6** This file is part of the "GeMA" software. It's use should respect
7** the terms in the license agreement that can be found together
8** with this source code.
9** It is provided AS IS, with NO WARRANTY OF ANY KIND,
10** INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11** A PARTICULAR PURPOSE.
12**
13************************************************************************/
14
27#ifndef _GEMA_PLUGIN_HYDRAULIC_MATERIAL_PIPEFLOW_H_
28#define _GEMA_PLUGIN_HYDRAULIC_MATERIAL_PIPEFLOW_H_
29
30#include <gmpFemPhysicsCommonMaterial.h>
31
32#include "gmpHydraulicConfig.h"
33#include "gmpHydraulicPipe.h"
34#include <gmMathUtils.h>
35#include <gmTrace.h>
36
37
38
39class GMP_HYDRAULIC_PHYSICS_API_EXPORT GmpMaterialPipeFlow: public GmpFemPhysicsCommonMaterial
40{
41protected:
52
55 {
58 QFLOW_GA_ID,
60
61 // ------ NO ADDING BELOW THIS LINE
63 };
64
65public:
66
68 GmpMaterialPipeFlow(int typeIndex, QString typeName, const GmLogCategory& logger)
69 : GmpFemPhysicsCommonMaterial(typeIndex, typeName, logger) {}
70
72 static GmpFemPhysicsCommonMaterial* instance(GmSimulationData* simulation, int typeIndex, QString typeName, const GmLogCategory& logger)
73 {
74 Q_UNUSED(simulation);
75 return new GmpMaterialPipeFlow(typeIndex, typeName, logger);
76 }
77
78 // set pipe material map
79 virtual const QVariantMap* materialMetaDataMap()
80 {
81 S_TRACE();
82
83 static QVariantMap m;
84
85 if (m.isEmpty())
86 {
87 // Adds material properties
88 m["properties"] = GmpFemPhysicsCommon::ValueList()
89 << GmpFemPhysicsCommon::ScalarValue(Dc_ID, "Dp", QObject::tr("Pipe diameter"), "m", true)
90 << GmpFemPhysicsCommon::ScalarValue(Uf_ID, "uf", QObject::tr("Dynamic fluid viscosity"), "kPa*s", true)
91 << GmpFemPhysicsCommon::ScalarValue(MFw_ID, "Mfw", QObject::tr("Interface biot modulus"), "kPa/m", false)
92 << GmpFemPhysicsCommon::ScalarValue(GW_ID, "gw", QObject::tr("Fluid specific weight"), "kN/m3", true)
93 << GmpFemPhysicsCommon::ScalarValue(W_ID, "wr", QObject::tr("Wall roughness"), "m", true)
94 << GmpFemPhysicsCommon::ScalarValue(rhof_ID, "rhow", QObject::tr("Water density"), "kg/m3", true);
95
96
97 // Adds material gauss attributes
98 m["gaussAttributes"] = GmpFemPhysicsCommon::ValueList()
99 << GmpFemPhysicsCommon::ScalarValue(FR_GA_ID, "FR", QObject::tr("flow regime"), " ", true, false, 2)
100 << GmpFemPhysicsCommon::HistoryValue(FROLD_GA_ID, FR_GA_ID, 1, true)
101 << GmpFemPhysicsCommon::ScalarValue(QFLOW_GA_ID, "Qf", QObject::tr("Flow in the pipe element"), "m3/s", true, false, 1)
102 << GmpFemPhysicsCommon::ScalarValue(RE_GA_ID, "Re", QObject::tr("Reynolds number of the flow in the pipe"), " ", true, false, 1);
103 }
104
105 return &m;
106 }
107
109 virtual double pipeDiameter(const GmElement* e, const GmVector* coord, int ip) const
110 {
111 S_TRACE();
112 assert(e);
113 return propertyAc(Dc_ID)->scalarValueAt(e, coord, ip);
114 }
115
117 virtual double fluidViscosity(const GmElement* e, const GmVector* coord, int ip) const
118 {
119 S_TRACE();
120 assert(e);
121 return propertyAc(Uf_ID)->scalarValueAt(e, coord, ip);
122 }
123
125 virtual double fluidSpecificWeight(const GmElement* e, const GmVector* coord, int ip) const
126 {
127 S_TRACE();
128 assert(e);
129 return propertyAc(GW_ID)->scalarValueAt(e, coord, ip);
130 }
131
133 virtual double pipeWallRoughness(const GmElement* e, const GmVector* coord, int ip) const
134 {
135 S_TRACE();
136 assert(e);
137 return propertyAc(W_ID)->scalarValueAt(e, coord, ip);
138 }
139
141 virtual double fluidDensity(const GmElement* e, const GmVector* coord, int ip) const
142 {
143 S_TRACE();
144 assert(e);
145
146 return propertyAc(rhof_ID)->scalarValueAt(e, coord, ip);
147 }
148
150 virtual double frictionFactor(const GmElement* e, const GmVector* coord, int ip, double dp) const
151 {
152 S_TRACE();
153 assert(e);
154 // Get properties
155 GmGaussAccessor* ReAcc = gaussAttrAc(RE_GA_ID);
156 double w = pipeWallRoughness(e, coord, ip);
157 double NRe = ReAcc->scalarValueAt(e, ip, coord);
158 double fs, ft, fr, fmax, R, dR, deltaft;
159 int it = 1, iterMAX = 30;
160
161
162 // 1) Compute the friction factor for smooth turbulence, fs
163 fs = 0.3164*pow(NRe, -0.25);
164
165 // 2) Compute the friction factor with respect to the transition between smooth and rough turbulence, ft
166 // Initialize thhe parameters
167 ft = fs;
168 R = pow(ft, -0.50) - 1.14 + 2.0*log10(w / dp + 9.35 / NRe * pow(ft, -0.50));
169
170 // Newton-Raphson's procedure
171 while (abs(R) >= 1e-10)
172 {
173 // Derivative of residual function R with respect dgamma
174 dR = -0.50 / pow(ft, 1.50) - 9.350 / (NRe*pow(ft, 1.50)*(w / dp + 9.35 / NRe * pow(ft, -0.50))*log(10.0));
175
176 // Increment of dgamma
177 deltaft = -R / dR;
178
179 // Update
180 ft += deltaft;
181
182 // Check the residual function
183 R = pow(ft, -0.50) - 1.14 + 2.0*log10(w / dp + 9.35 / NRe * pow(ft, -0.50));
184
185 if (it == iterMAX)
186 {
187 gmErrorMsg(logger(), "Error to compute the friction factor. No convergence");
188 }
189
190 it++;
191
192 }
193
194 // 3) Compute the friction factor for rough turbulence, fr
195 fr = pow(1 / (1.14 - 2.0*log10(w / dp)),2.0);
196
197 // The friction factor is the maximmum among fs, ft and fr
198 fmax = (fs > ft) ? fs : ft;
199 fmax = (fmax > fr) ? fmax : fr;
200
201 return fmax;
202 }
203
205 virtual double interfaceBiotModulus(const GmElement* e, const GmVector* coord, int ip) const
206 {
207 S_TRACE();
208 assert(e);
209 if (propertyAc(MFw_ID) == NULL)
210 {
211 return 0;
212 }
213 return propertyAc(MFw_ID)->scalarValueAt(e, coord, ip);
214 }
215
217 virtual double pipeConductivity(const GmElement* e, const GmVector* coord, int ip, GmGaussAccessor* DpAcc, GmVector& Pe, double L) const
218 {
219 S_TRACE();
220 assert(e);
221 GmGaussAccessor* oldFrAcc = gaussAttrAc(FROLD_GA_ID); // read from old FR
222 double isTurbulent = oldFrAcc->scalarValueAt(e, ip, coord);
223 double kl = 0.0;
224 double dp = DpAcc->scalarValueAt(e, ip, coord);
225 double uf = fluidViscosity(e, coord, ip);
226 double gw = fluidSpecificWeight(e, coord, ip);
227 double rhoW = fluidDensity(e, coord, ip);
228 double w = pipeWallRoughness(e, coord, ip);
229 double dH = abs(Pe(0) - Pe(1))/gw; // head loss in length units
230
231 // Compute the gravitational acceleration
232 double gAc = 1000.0 * gw / rhoW; // m/s2
233
234 // computes the cubic law
235 if (uf > 0.0)
236 {
237 if (dp > 0.0)
238 {
239
240 // Laminar case
241 if (isTurbulent==0)
242 {
243 kl = arma::datum::pi*pow(dp, 4.0) / (128.0 * uf);
244 }
245
246 // Turbulent case
247 // For turbulent the pipe conductivity is computed based on the Darcy-Weisbach and Colebrook equations as presented
248 // by Swammee and Jain (1976). In this expression, the friction factor is explicitly shown and it is independent of
249 // the Reynolds number.
250 else
251 {
252
253 double nu = 1000.0*uf / rhoW; // m2/s
254 double A = w / (3.7*dp);
255 double B = 2.51*nu / dp;
256 double alpha = 2.0*gAc*dp*abs(dH) / L;
257 double f1 = -arma::datum::pi * pow(dp, 2.0)*sqrt(2.0*gAc*dp*L / abs(dH)) / (2.0*gw);
258 double f2 = log10(A + B / sqrt(alpha));
259
260 kl = f1 * f2;
261
262 }
263
264 // According to Kaufmann and Braun (1999)
265 //else
266 //{
267 // // Get the friction factor
268 // double f = frictionFactor(e, coord, ip, dp);
269 // double alpha = gAc * dp*L / (8.0*f*dH);
270 // kl = -arma::datum::pi*pow(dp, 2.0)*sqrt(alpha)/ (gw);
271 //}
272
273 // Swamee & Swammee (2007)
274 //if (dH < 1e-10)
275 //{
276 // dH = 1e-10;
277 //}
278
279 // double nu = 1000.0*uf / rhoW; // m2/s
280 // double alpha = gAc * dp*dH / L;
281 // double C1 = pow(128 * nu / (arma::datum::pi*dp*sqrt(alpha)), 4.0);
282 // double C2 = 1.153*pow(pow(415 * nu / (dp*sqrt(alpha)), 8.0) - log(w / (3.7*dp) + 1.775*nu / (dp*sqrt(alpha))), -4.0);
283 // double C = dp * dp / gw * pow(C1 + C2, -0.25);
284 // kl = C * sqrt(gAc*dp*L / (dH));
285
286
287 }
288 }
289 else
290 {
291 assert(uf != 0 && "Ufw Dynamic viscosity must be different to zero");
292 }
293
294 return kl;
295 }
296
298 virtual double pipeTangentConductivity(const GmElement* e, const GmVector* coord, int ip, GmGaussAccessor* DpAcc, GmVector& Pe, double L) const
299 {
300 S_TRACE();
301 assert(e);
302 GmGaussAccessor* oldFrAcc = gaussAttrAc(FROLD_GA_ID); // read from old FR
303 double isTurbulent = oldFrAcc->scalarValueAt(e, ip, coord);
304 double kt = 0.0;
305 double dp = DpAcc->scalarValueAt(e, ip, coord);
306 double uf = fluidViscosity(e, coord, ip);
307 double gw = fluidSpecificWeight(e, coord, ip);
308 double rhoW = fluidDensity(e, coord, ip);
309 double w = pipeWallRoughness(e, coord, ip);
310 double dH = (Pe(0) - Pe(1))/ gw; // head loss in length units
311 double signaldH;
312
313 if (dH >= 0)
314 {
315 signaldH = 1.0;
316
317 }
318 else
319 {
320 signaldH = -1.0;
321 }
322
323 // Compute the gravitational acceleration
324 double gAc = 1000.0*gw / rhoW; // m2/s
325
326 // computes the cubic law
327 if (uf > 0.0)
328 {
329 if (dp > 0.0)
330 {
331 // Laminar case
332 if (isTurbulent == 0)
333 {
334
335 kt = arma::datum::pi * pow(dp, 4.0) / (128.0 * uf);
336 }
337
338 // Turbulent case
339 // For turbulent the pipe conductivity is computed based on the Darcy-Weisbach and Colebrook equations as presented
340 // by Swammee and Jain (1976). In this expression, the friction factor is explicitly shown and it is independent of
341 // the Reynolds number.
342 else
343 {
344 double nu = 1000.0*uf / rhoW; // m2/s
345 double A = w / (3.7*dp);
346 double B = 2.51*nu / dp;
347 double alpha = 2.0*gAc*dp*abs(dH) / L;
348 double f1 = -arma::datum::pi * pow(dp, 2.0)*sqrt(2.0*gAc*dp*L / abs(dH)) / (2.0*gw);
349 double f2 = log10(A + B / sqrt(alpha));
350 double df1h1 = signaldH * arma::datum::pi*pow(dp, 3.0)*gAc*L / (4.0*gw*pow(dH, 2.0))*sqrt(2.0*abs(dH) / (gAc*dp*L));
351 double df2h1 = -1.0*signaldH*B / (2.0*abs(dH)*(A*sqrt(alpha) + B)*log(10));
352
353 kt = dH * (df1h1*f2 + f1 * df2h1) + f1 * f2;
354 }
355
356 }
357 }
358 else
359 {
360 assert(uf != 0 && "Ufw Dynamic viscosity must be different to zero");
361 }
362
363 return kt;
364 }
365
368 virtual void ckeckFlowRegime(const GmElement* e, const GmVector* coord, int ip, GmGaussAccessor* DpAcc, GmVector& Fi) const
369 {
370 S_TRACE();
371 GmGaussAccessor* FrAcc = gaussAttrAc(FR_GA_ID); // save no new FR
372 double Qflow = abs(Fi(0));
373 double dp = DpAcc->scalarValueAt(e, ip, coord);
374 double uf = fluidViscosity(e, coord, ip);
375 double rhoW = fluidDensity(e, coord, ip);
376 double nu = 1000.0*uf / rhoW; // m2/s
377 double Re = 4.0*Qflow / (arma::datum::pi*nu*dp); // Compute the Reynolds number
378
379
380 // Check if the flow is turbulent (Re > 2200)
381 if (Re > 2200)
382 {
383 FrAcc->setScalarValue(e, ip, 1); // turbulent
384 }
385 else
386 {
387 FrAcc->setScalarValue(e, ip, 0); // laminar
388 }
389
391 GmGaussAccessor* QfAcc = gaussAttrAc(QFLOW_GA_ID);
392 QfAcc->setScalarValue(e, ip, Qflow);
393
394 // Set the Reynolds number
395 GmGaussAccessor* ReAcc = gaussAttrAc(RE_GA_ID);
396 ReAcc->setScalarValue(e, ip, Re);
397 }
398
399};
400
401#endif
Definition gmpMaterialPipeFlow.h:40
virtual double fluidViscosity(const GmElement *e, const GmVector *coord, int ip) const
Returns the dynamic fluid viscosity.
Definition gmpMaterialPipeFlow.h:117
virtual double pipeDiameter(const GmElement *e, const GmVector *coord, int ip) const
Returns the initial fracture opening.
Definition gmpMaterialPipeFlow.h:109
virtual double pipeTangentConductivity(const GmElement *e, const GmVector *coord, int ip, GmGaussAccessor *DpAcc, GmVector &Pe, double L) const
Returns the hydraulic conductivity of Pipe [m^4/(kPa*s)].
Definition gmpMaterialPipeFlow.h:298
virtual double frictionFactor(const GmElement *e, const GmVector *coord, int ip, double dp) const
Returns friction factor as presented by Kaufmann.
Definition gmpMaterialPipeFlow.h:150
virtual double pipeWallRoughness(const GmElement *e, const GmVector *coord, int ip) const
Returns the wall roughness of the pipe.
Definition gmpMaterialPipeFlow.h:133
PipePropertyIds
IDs for saturated material element properties.
Definition gmpMaterialPipeFlow.h:44
@ MFw_ID
Id for retrieving the discontinuity Biot's Modulus.
Definition gmpMaterialPipeFlow.h:47
@ rhof_ID
Id for retrieving the water density.
Definition gmpMaterialPipeFlow.h:50
@ Uf_ID
Id for retrieving the dynamic fluid viscosity.
Definition gmpMaterialPipeFlow.h:46
@ Dc_ID
Id for retrieving the pipe diameter.
Definition gmpMaterialPipeFlow.h:45
@ W_ID
Id for retrieving the wall roughness of the pipe.
Definition gmpMaterialPipeFlow.h:49
@ GW_ID
Id for retrieving the specific weight of the fluid.
Definition gmpMaterialPipeFlow.h:48
GmpMaterialPipeFlow(int typeIndex, QString typeName, const GmLogCategory &logger)
Constructor. Gets as parameters the material index and its name.
Definition gmpMaterialPipeFlow.h:68
virtual void ckeckFlowRegime(const GmElement *e, const GmVector *coord, int ip, GmGaussAccessor *DpAcc, GmVector &Fi) const
Definition gmpMaterialPipeFlow.h:368
virtual double fluidSpecificWeight(const GmElement *e, const GmVector *coord, int ip) const
Returns the specific weight of the fluid.
Definition gmpMaterialPipeFlow.h:125
virtual double fluidDensity(const GmElement *e, const GmVector *coord, int ip) const
Returns gravitational accelaration.
Definition gmpMaterialPipeFlow.h:141
static GmpFemPhysicsCommonMaterial * instance(GmSimulationData *simulation, int typeIndex, QString typeName, const GmLogCategory &logger)
A "factory" function used to register the material with the physics material factory.
Definition gmpMaterialPipeFlow.h:72
virtual double pipeConductivity(const GmElement *e, const GmVector *coord, int ip, GmGaussAccessor *DpAcc, GmVector &Pe, double L) const
Returns the hydraulic conductivity of Pipe [m^4/(kPa*s)].
Definition gmpMaterialPipeFlow.h:217
pipeGaussAttrIds
IDs for Gauss attributes of pipe material.
Definition gmpMaterialPipeFlow.h:55
@ FR_GA_ID
Base Id for Gauss attribute(s) used to store the calculated Flow regime.
Definition gmpMaterialPipeFlow.h:56
@ RE_GA_ID
Base Id for Gauss attribute(s) used to store the Reynolds number.
Definition gmpMaterialPipeFlow.h:59
@ NUM_GA_IDS
The number of gauss attributes.
Definition gmpMaterialPipeFlow.h:62
@ FROLD_GA_ID
Id for retrieving the plastic strain accessor at the previous state (old Flow regime)
Definition gmpMaterialPipeFlow.h:57
virtual double interfaceBiotModulus(const GmElement *e, const GmVector *coord, int ip) const
Returns the discontinuity Biot's Modulus.
Definition gmpMaterialPipeFlow.h:205
#define S_TRACE()
arma::vec GmVector
Declaration of useful configuration definitions for the plugin library.
Declaration of the GmpHydraulicPipe classes.
QString tr(const char *sourceText, const char *disambiguation, int n)