LifeV
Womersley.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Womersley Analytical Solution
30 
31  @author Mauro Perego <mauro@mathcs.emory.edu>
32  @contributor Umberto Villa <uvilla@emory.edu>
33  @maintainer Umberto Villa <uvilla@emory.edu>
34 
35  @date 11-12-2009
36 
37  Implementation
38  */
39 
40 #include <lifev/core/LifeV.hpp>
41 #include <lifev/navier_stokes/function/Womersley.hpp>
42 #include <lifev/navier_stokes/function/bessel/bessel.hpp>
43 
44 namespace LifeV
45 {
46 const Real Pi = 3.14159265358979323846264338328;
47 
48 Real Womersley::uexact ( const Real& t, const Real& /*x*/, const Real& y, const Real& z, const ID& i)
49 {
50  Real r = std::sqrt (z * z + y * y);
51  std::complex<Real> z2, b2;
52  z2 = 2.*r / S_D * S_z1;
53  bessel::cbessjy01 (z2, b2, S_cj1, S_cy0, S_cy1, S_cj0p, S_cj1p, S_cy0p, S_cy1p);
54  Real u = real (S_A / S_L / S_rho / S_wi * (1. - b2 / S_b1) * std::exp (S_wi * t) );
55  switch (i)
56  {
57  case 0: //u_1
58  return u;//-4*x*y*y; //u-4*x*y*y;
59  case 1: //u_2
60  return 0.;//y*y*y;
61  case 2:
62  return 0.;
63  default:
64  exit (1);
65  }
66  return 1.;
67 }
68 
69 Real Womersley::pexact ( const Real& t, const Real& x, const Real& /*y*/, const Real& /*z*/, const ID& /* i */ )
70 {
71  return S_A / S_L * (S_L - x) * std::cos (S_w * t);
72 }
73 
74 Real Womersley::grad_u ( const UInt& icoor, const Real& t, const Real& /*x*/, const Real& y, const Real& z, const ID& i )
75 {
76  Real r = std::sqrt (y * y + z * z);
77  std::complex<Real> z2, b2;
78  z2 = 2.*r / S_D * S_z1;
79  bessel::cbessjy01 (z2, b2, S_cj1, S_cy0, S_cy1, S_cj0p, S_cj1p, S_cy0p, S_cy1p);
80  b2 = -2. / S_D * S_z1 * S_cj0p;
81  Real u_r = real (S_A / S_L / S_rho / S_wi * +b2 / S_b1 * std::exp (S_wi * t) );
82 
83  switch (icoor)
84  {
85  case 0:
86  switch (i)
87  {
88  case 0:
89  return 0.;
90  case 1:
91  return 0.;
92  case 2:
93  return 0.;
94  default:
95  exit (1);
96  }
97  case 1: // u_y
98  switch (i)
99  {
100  case 0:
101  return u_r / r * y;
102  case 1:
103  return 0.;
104  case 2:
105  return 0.;
106  default:
107  exit (1);
108  }
109  case 2:
110  switch (i)
111  {
112  case 0:
113  return u_r / r * z;
114  case 1:
115  return 0.;
116  case 2:
117  return 0.;
118  default:
119  exit (1);
120  }
121  default:
122  exit (1);
123  }
124  return 1.;
125 }
126 
127 Real Womersley::f ( const Real& /* t */, const Real& /*x*/ , const Real& /*y*/ , const Real& /* z */, const ID& i )
128 {
129  switch (i)
130  {
131  case 0:
132  return 0.;
133  case 1:
134  return 0.;
135  case 2:
136  return 0.;
137  default:
138  exit (1);
139  }
140  return 1.;
141 }
142 
143 Real Womersley::xexact ( const Real& t,
144  const Real& x,
145  const Real& y,
146  const Real& z,
147  const ID& i )
148 {
149  switch (i)
150  {
151  case 0: //u_1
152  case 1: //u_2
153  return uexact (t, x, y, z, i);
154  case 2: //pressure
155  return pexact (t, x, y, z, 1);
156  break;
157  default:
158  exit (1);
159  }
160  return 1.;
161 }
162 
163 
164 
165 
166 Real Womersley::x0 ( const Real& t, const Real& x, const Real& y, const Real& z, const ID& i )
167 {
168  return xexact (t, x, y, z, i);
169 }
170 
171 // Initial velocity
172 Real Womersley::u0 ( const Real& t, const Real& x, const Real& y, const Real& z, const ID& i )
173 {
174  return uexact (t, x, y, z, i);
175 }
176 
177 // Initial pressure
178 Real Womersley::p0 ( const Real& t, const Real& x, const Real& y, const Real& z, const ID& /*i*/ )
179 {
180  return pexact (t, x, y, z, 0);
181 }
182 
183 //we suppose that the problem geometry is the cylinder having axis x, origin (0,0,0), diameter D and height L
184 Real Womersley::fNeumann ( const Real& t, const Real& x, const Real& y, const Real& z, const ID& i )
185 {
186  Real r = std::sqrt (y * y + z * z);
187  Real n[3] = {0., 0., 0.};
188  Real out = 0.;
189  if ( x < 1e-6 / S_L )
190  {
191  n[0] = -1.;
192  }
193  else if ( x > S_L * (1 - 1e-6) )
194  {
195  n[0] = 1.;
196  }
197  else if ( r > S_D / 2.*0.9 )
198  {
199  n[1] = y / r;
200  n[2] = z / r;
201  }
202  else
203  {
204  // std::cout << "strange point: x=" << x << " y=" << y << " z=" << z
205  // << std::endl;
206  }
207 
208  for (UInt k = 0; k < nDimensions; k++) //mu gradu n
209  {
210  out += S_mu * grad_u (k, t, x, y, z, i) * n[k];
211  }
212 
213  if (S_flagStrain)
214  for (UInt k = 0; k < nDimensions; k++) //mu gradu^T n
215  {
216  out += S_mu * grad_u (i, t, x, y, z, k) * n[k];
217  }
218 
219  out -= pexact (t, x, y, z, i) * n[i];
220 
221 
222  return out;
223 }
224 
225 Real Womersley::normalVector ( const Real& /*t*/, const Real& x, const Real& y,
226  const Real& z, const ID& i )
227 {
228  Real r = std::sqrt (y * y + z * z);
229  Real n[3] = {0., 0., 0.};
230  if ( x < 1e-6 / S_L )
231  {
232  n[0] = -1.;
233  }
234  else if ( x > S_L * (1 - 1e-6) )
235  {
236  n[0] = 1.;
237  }
238  else if ( r > S_D / 2.*0.9 )
239  {
240  n[1] = y / r;
241  n[2] = z / r;
242  }
243  else
244  {
245  // std::cout << "strange point: x=" << x << " y=" << y << " z=" << z
246  // << std::endl;
247  }
248  return n[i];
249 }
250 
251 //we suppose that the problem geometry is the cylinder having axis x, origin (0,0,0), diameter D and height L
252 Real Womersley::fShearStress ( const Real& t, const Real& x, const Real& y, const Real& z, const ID& i )
253 {
254  Real r = std::sqrt (y * y + z * z);
255  Real n[3] = {0., 0., 0.};
256  Real out = 0.;
257  if ( x < 1e-6 / S_L )
258  {
259  n[0] = -1.;
260  }
261  else if ( x > S_L * (1 - 1e-6) )
262  {
263  n[0] = 1.;
264  }
265  else if ( r > S_D / 2.*0.9 )
266  {
267  n[1] = y / r;
268  n[2] = z / r;
269  }
270  else
271  {
272  // std::cout << "strange point: x=" << x << " y=" << y << " z=" << z
273  // << std::endl;
274  }
275 
276  for (UInt k = 0; k < nDimensions; k++) //mu gradu n
277  {
278  out += S_mu * grad_u (k, t, x, y, z, i) * n[k];
279  }
280 
281  if (S_flagStrain)
282  for (UInt k = 0; k < nDimensions; k++) //mu gradu^T n
283  {
284  out += S_mu * grad_u (i, t, x, y, z, k) * n[k];
285  }
286 
287  return out;
288 }
289 
290 //we suppose that the problem geometry is the cylinder having axis x, origin (0,0,0), diameter D and height L
291 Real Womersley::fWallShearStress ( const Real& t, const Real& x, const Real& y, const Real& z, const ID& i )
292 {
293  Real r = std::sqrt (y * y + z * z);
294  Real n[3] = {0., 0., 0.};
295  if ( x < 1e-6 / S_L )
296  {
297  n[0] = -1.;
298  }
299  else if ( x > S_L * (1 - 1e-6) )
300  {
301  n[0] = 1.;
302  }
303  else if ( r > S_D / 2.*0.9 )
304  {
305  n[1] = y / r;
306  n[2] = z / r;
307  }
308  else
309  {
310  //std::cout << "strange point: x=" << x << " y=" << y << " z=" << z
311  // << std::endl;
312  }
313 
314  // wss = s_n - ( s_n \cdot n ) n
315  Real wss = 0.;
316  Real s_n_n (0.);
317  // this is the i-component of the normal stress
318  wss = fShearStress (t, x, y, z, i);
319 
320  for (UInt k = 0; k < nDimensions; k++) // ( s_n \cdot n )
321  {
322  s_n_n += fShearStress (t, x, y, z, k) * n[k];
323  }
324 
325  wss -= s_n_n * n[i];
326 
327  return wss;
328 }
329 
330 void Womersley::setParamsFromGetPot ( const GetPot& dataFile )
331 {
332  S_mu = dataFile ( "fluid/physics/viscosity", 1. );
333  S_flagStrain = dataFile ( "fluid/physics/flag_strain", 0 );
334  S_nu = S_mu / dataFile ( "fluid/physics/density", 1. );
335  S_D = dataFile ( "fluid/problem/D", 1. );
336  S_T = dataFile ( "fluid/problem/T", 1. );
337  S_rho = dataFile ( "fluid/physics/density", 1. );
338  S_W0 = S_D / 2 * std::sqrt (2 * Pi / S_nu / S_T);
339  S_L = dataFile ( "fluid/problem/L", 1. );
340  S_A = dataFile ( "fluid/problem/A", 16 * S_mu / S_D / S_D * S_L * S_L);
341  S_ii = std::complex<Real> (0., 1.);
342  S_w = 2.*Pi / S_T;
343  S_wi = S_w * S_ii;
344  S_z1 = S_W0 * std::pow (S_ii, 1.5);
345  bessel::cbessjy01 (S_z1, S_b1, S_cj1, S_cy0, S_cy1, S_cj0p, S_cj1p, S_cy0p, S_cy1p);
346 
347 }
348 
349 void Womersley::showMe()
350 {
351  std::cout << "Kynetic viscosity " << S_nu << std::endl;
352  std::cout << "Pipe radius " << S_D / 2. << " Pipe lenght " << S_L << std::endl;
353  std::cout << "Oscillation period " << S_T << std::endl;
354  std::cout << "Pressure Drop " << S_A << std::endl;
355  std::cout << "Womersley Number " << S_D / 2.*std::sqrt (S_w / S_nu) << std::endl;
356 }
357 
358 Real Womersley::S_nu;
359 Real Womersley::S_mu;
360 Int Womersley::S_flagStrain;
361 Real Womersley::S_D;
362 Real Womersley::S_rho;
363 Real Womersley::S_T;
364 Real Womersley::S_W0;
365 Real Womersley::S_L;
366 Real Womersley::S_A;
367 Real Womersley::S_w;
368 std::complex<Real> Womersley::S_cj1, Womersley::S_cy0, Womersley::S_cy1,
369  Womersley::S_cj0p, Womersley::S_cj1p, Womersley::S_cy0p, Womersley::S_cy1p ,
370  Womersley::S_z1, Womersley::S_b1 , Womersley::S_ii, Womersley::S_wi;
371 } // namespace LifeV
double operator()(const char *VarName, const double &Default) const
Definition: GetPot.hpp:2033
Definition: bessik.cpp:9
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
uint32_type ID
IDs.
Definition: LifeV.hpp:194
int cbessjy01(std::complex< double > z, std::complex< double > &cj0, std::complex< double > &cj1, std::complex< double > &cy0, std::complex< double > &cy1, std::complex< double > &cj0p, std::complex< double > &cj1p, std::complex< double > &cy0p, std::complex< double > &cy1p)
Definition: cbessjy.cpp:18
double Real
Generic real data.
Definition: LifeV.hpp:175
int operator()(const char *VarName, int Default) const
Definition: GetPot.hpp:2021
const UInt nDimensions(NDIM)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191