Plugins
upwind_interface.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2015: G-CSC, Goethe University Frankfurt
3  * Author: Andreas Vogel
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG__NAVIER_STOKES__UPWIND_INTERFACE__
34 #define __H__UG__NAVIER_STOKES__UPWIND_INTERFACE__
35 
36 //#define UG_NSUPWIND_ASSERT(cond, exp)
37 // include define below to assert arrays used in stabilization
38 #define UG_NSUPWIND_ASSERT(cond, exp) UG_ASSERT((cond), exp)
39 
40 #include <vector>
41 
46 
47 namespace ug{
48 namespace NavierStokes{
49 
51 // Interface for Upwinds on collocated grid (stabilization method)
53 
54 
55 template <int dim>
57 {
58  protected:
61 
62  public:
64  static const size_t maxNumSCVF = traits::maxNumSCVF + 10;
65 
67  static const size_t maxNumSH = traits::maxNSH + 10;
68 
69  public:
72 
73  public:
76  : m_numScvf(0), m_numSh(0),
77  m_bNonZeroShapeIp(true)
78  {
79  m_vComputeFunc.clear();
80  }
81 
83  size_t num_sh() const {return m_numSh;}
84 
86  size_t num_scvf() const {return m_numScvf;}
87 
89  number upwind_conv_length(size_t scvf) const
90  {
91  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
92  return m_vUpConvLength[scvf];
93  }
94 
96  number downwind_conv_length(size_t scvf) const
97  {
98  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
99  return m_vDownConvLength[scvf];
100  }
101 
103  MathVector<dim> upwind_vel(const size_t scvf,
104  const LocalVector& CornerVel,
105  const MathVector<dim> vStdVel[]) const;
106 
108  number upwind_shape_sh(size_t scvf, size_t sh) const
109  {
110  // UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
111  // UG_NSUPWIND_ASSERT(sh < m_numSh, "Invalid index");
112  return m_vvUpShapeSh[scvf][sh];
113  }
114 
116  number downwind_shape_sh(size_t scvf, size_t sh) const
117  {
118  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
119  UG_NSUPWIND_ASSERT(sh < m_numSh, "Invalid index");
120  return m_vvDownShapeSh[scvf][sh];
121  }
122 
124  bool non_zero_shape_ip() const {return m_bNonZeroShapeIp;}
125 
127  number upwind_shape_ip(size_t scvf, size_t scvf2) const
128  {
129  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index: " << scvf);
130  UG_NSUPWIND_ASSERT(scvf2 < m_numScvf, "Invalid index2: " << scvf2);
131  return m_vvUpShapeIp[scvf][scvf2];
132  }
133 
135  number downwind_shape_ip(size_t scvf, size_t scvf2) const
136  {
137  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
138  UG_NSUPWIND_ASSERT(scvf2 < m_numScvf, "Invalid index");
139  return m_vvDownShapeIp[scvf][scvf2];
140  }
141 
143  void update(const FVGeometryBase* geo,
144  const MathVector<dim> vStdVel[])
145  {
146  update_upwind(geo, vStdVel);
147  }
148 
150  void update_upwind(const FVGeometryBase* geo,
151  const MathVector<dim> vStdVel[])
152  {
154  }
155 
158  const MathVector<dim> vStdVel[])
159  {
160  MathVector<dim> vDownIPVel[maxNumSCVF];
161  for(size_t ip = 0; ip < m_numScvf; ++ip)
162  VecScale(vDownIPVel[ip], vStdVel[ip], -1.0);
163 
165  }
166 
168  // internal handling
170 
171  protected:
173  void set_shape_ip_flag(bool flag) {m_bNonZeroShapeIp = flag;}
174 
176  number& upwind_shape_sh(size_t scvf, size_t sh)
177  {
178  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
179  UG_NSUPWIND_ASSERT(sh < m_numSh, "Invalid index");
180  return m_vvUpShapeSh[scvf][sh];
181  }
182 
184  number& downwind_shape_sh(size_t scvf, size_t sh)
185  {
186  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
187  UG_NSUPWIND_ASSERT(sh < m_numSh, "Invalid index");
188  return m_vvDownShapeSh[scvf][sh];
189  }
190 
192  number& upwind_shape_ip(size_t scvf, size_t scvf2)
193  {
194  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
195  UG_NSUPWIND_ASSERT(scvf2 < m_numScvf, "Invalid index");
196  return m_vvUpShapeIp[scvf][scvf2];
197  }
198 
200  number& downwind_shape_ip(size_t scvf, size_t scvf2)
201  {
202  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
203  UG_NSUPWIND_ASSERT(scvf2 < m_numScvf, "Invalid index");
204  return m_vvDownShapeIp[scvf][scvf2];
205  }
206 
209  {
210  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
211  return m_vUpConvLength[scvf];
212  }
213 
216  {
217  UG_NSUPWIND_ASSERT(scvf < m_numScvf, "Invalid index");
218  return m_vDownConvLength[scvf];
219  }
220 
222  size_t m_numScvf;
223 
225  size_t m_numSh;
226 
230 
234 
237 
241 
243  void compute(const FVGeometryBase* geo,
244  const MathVector<dim> vIPVel[maxNumSCVF],
245  number vUpShapeSh[maxNumSCVF][maxNumSH],
246  number vUpShapeIp[maxNumSCVF][maxNumSCVF],
247  number vConvLength[maxNumSCVF])
248  {
249  (*(m_vComputeFunc[m_id]))(geo, vIPVel, vUpShapeSh, vUpShapeIp, vConvLength);
250  }
251 
253  // registering process
255  public:
257  template <typename TFVGeom, typename TAssFunc>
258  void register_update_func(TAssFunc func);
259 
261  template <typename TFVGeom, typename TAssFunc>
262  void register_update_ip_vel_func(TAssFunc func);
263 
265  template <typename TFVGeom>
266  void set_geometry_type();
267 
268  protected:
269 
271 // typedef void (this_type::*ComputeFunc)(
272  typedef void (*ComputeFunc)(
273  const FVGeometryBase* obj,
274  const MathVector<dim> vIPVel[maxNumSCVF],
275  number vUpShapeSh[maxNumSCVF][maxNumSH],
276  number vUpShapeIp[maxNumSCVF][maxNumSCVF],
277  number vConvLength[maxNumSCVF]);
278 
280  std::vector<ComputeFunc> m_vComputeFunc;
281 
283  int m_id;
284 };
285 
286 // register a update function for a Geometry
287 template <int dim>
288 template <typename TFVGeom, typename TAssFunc>
289 void
291 register_update_func(TAssFunc func)
292 {
293 // get unique geometry id
294  size_t id = GetUniqueFVGeomID<TFVGeom>();
295 
296 // make sure that there is enough space
297  if((size_t)id >= m_vComputeFunc.size())
298  m_vComputeFunc.resize(id+1, NULL);
299 
300 // set pointer
301  m_vComputeFunc[id] = reinterpret_cast<ComputeFunc>(func);
302 }
303 
304 
305 // set the Geometry type to use for next updates
306 template <int dim>
307 template <typename TFVGeom>
308 void
311 {
312 
313 // get unique geometry id
314  size_t id = GetUniqueFVGeomID<TFVGeom>();
315 
316 // check that function exists
317  if(id >= m_vComputeFunc.size() || m_vComputeFunc[id] == NULL)
318  UG_THROW("No update function registered for Geometry "<<id);
319 
320 // set current geometry
321  m_id = id;
322 
323 // set sizes
324  static TFVGeom& geo = GeomProvider<TFVGeom>::get();
325  m_numScvf = geo.num_scvf();
326  m_numSh = geo.num_sh();
327  UG_NSUPWIND_ASSERT(m_numScvf <= maxNumSCVF, "Invalid index");
328  UG_NSUPWIND_ASSERT(m_numSh <= maxNumSH, "Invalid index");
329 
330 }
331 
332 
334 template <int dim>
337 upwind_vel(const size_t scvf,
338  const LocalVector& CornerVel,
339  const MathVector<dim> vStdVel[]) const
340 {
341 // reset result
342  MathVector<dim> vel; VecSet(vel, 0.0);
343 
344 // add corner shapes
345  for(size_t sh = 0; sh < num_sh(); ++sh)
346  for(int d = 0; d < dim; ++d)
347  vel[d] += upwind_shape_sh(scvf, sh) * CornerVel(d, sh);
348 
349 // done if only depending on shapes
350  if(!non_zero_shape_ip()) return vel;
351 
352 // compute ip vel
353  for(size_t scvf2 = 0; scvf2 < num_scvf(); ++scvf2)
354  VecScaleAppend(vel, upwind_shape_ip(scvf, scvf2), vStdVel[scvf2]);
355 
356 // return value
357  return vel;
358 }
359 
360 template <template <class Elem, int WorldDim> class TFVGeom, int dim, typename TImpl>
362 {
363  public:
366 
367  protected:
368  static const size_t maxNumSCVF = base_type::maxNumSCVF;
369  static const size_t maxNumSH = base_type::maxNumSH;
370 
371  public:
374 
375  private:
377  {
378  register_func<RegularEdge>();
379  }
380 
382  {
383  register_func<Triangle>();
384  register_func<Quadrilateral>();
385  }
386 
388  {
389  register_func<Tetrahedron>();
390  register_func<Pyramid>();
391  register_func<Prism>();
392  register_func<Hexahedron>();
393  }
394 
395  template <typename TElem>
397  {
398  typedef TFVGeom<TElem, dim> TGeom;
399 // typedef void (TImpl::*TFunc)(
400  typedef void (*TFunc)(
401  const TGeom* obj,
402  const MathVector<dim> vIPVel[maxNumSCVF],
403  number vUpShapeSh[maxNumSCVF][maxNumSH],
404  number vUpShapeIp[maxNumSCVF][maxNumSCVF],
405  number vConvLength[maxNumSCVF]);
406 
407  getImpl().template register_update_func<TGeom, TFunc>(&TImpl::template compute<TElem>);
408  }
409 
410  protected:
412  TImpl& getImpl() {return static_cast<TImpl&>(*this);}
413 };
414 
416 template <int dim>
418 
419 } // namespace NavierStokes
420 } // end namespace ug
421 
422 #endif /* __H__UG__NAVIER_STOKES__UPWIND_INTERFACE__ */
function NavierStokes(fcts, subsets, discType)
static TGeom & get()
Definition: upwind_interface.h:57
void(* ComputeFunc)(const FVGeometryBase *obj, const MathVector< dim > vIPVel[maxNumSCVF], number vUpShapeSh[maxNumSCVF][maxNumSH], number vUpShapeIp[maxNumSCVF][maxNumSCVF], number vConvLength[maxNumSCVF])
type of update function
Definition: upwind_interface.h:272
int m_id
id of current geometry type
Definition: upwind_interface.h:283
void register_update_func(TAssFunc func)
register a update function for a Geometry
Definition: upwind_interface.h:291
size_t m_numSh
number of current shape functions (usually in corners)
Definition: upwind_interface.h:225
number & upwind_conv_length(size_t scvf)
non-const access to Convection Length
Definition: upwind_interface.h:208
number m_vDownConvLength[maxNumSCVF]
Definition: upwind_interface.h:229
size_t num_scvf() const
returns number of sub control volume faces
Definition: upwind_interface.h:86
bool m_bNonZeroShapeIp
flag if ip shapes are non-zero
Definition: upwind_interface.h:236
number m_vvDownShapeSh[maxNumSCVF][maxNumSH]
Definition: upwind_interface.h:233
std::vector< ComputeFunc > m_vComputeFunc
Vector holding all update functions.
Definition: upwind_interface.h:280
void register_update_ip_vel_func(TAssFunc func)
register a update function for a Geometry
number & upwind_shape_ip(size_t scvf, size_t scvf2)
non-const access to upwind shapes for ip vel
Definition: upwind_interface.h:192
void compute(const FVGeometryBase *geo, const MathVector< dim > vIPVel[maxNumSCVF], number vUpShapeSh[maxNumSCVF][maxNumSH], number vUpShapeIp[maxNumSCVF][maxNumSCVF], number vConvLength[maxNumSCVF])
compute values for new geometry and corner velocities
Definition: upwind_interface.h:243
void update_downwind(const FVGeometryBase *geo, const MathVector< dim > vStdVel[])
compute values for new geometry and corner velocities
Definition: upwind_interface.h:157
void set_shape_ip_flag(bool flag)
sets the shape ip flag
Definition: upwind_interface.h:173
number downwind_shape_ip(size_t scvf, size_t scvf2) const
upwind shapes for ip vel
Definition: upwind_interface.h:135
size_t num_sh() const
returns number of shapes
Definition: upwind_interface.h:83
number m_vvUpShapeIp[maxNumSCVF][maxNumSCVF]
upwind shapes for ip vels
Definition: upwind_interface.h:239
number & downwind_shape_sh(size_t scvf, size_t sh)
non-const access to upwind shapes for corner vel
Definition: upwind_interface.h:184
INavierStokesUpwind()
constructor
Definition: upwind_interface.h:75
number downwind_conv_length(size_t scvf) const
Convection Length.
Definition: upwind_interface.h:96
number downwind_shape_sh(size_t scvf, size_t sh) const
upwind shape for corner vel
Definition: upwind_interface.h:116
static const size_t maxNumSH
max number of shape functions
Definition: upwind_interface.h:67
INavierStokesUpwind< dim > this_type
Abbreviation for own type.
Definition: upwind_interface.h:71
void update(const FVGeometryBase *geo, const MathVector< dim > vStdVel[])
compute values for new geometry and corner velocities
Definition: upwind_interface.h:143
number m_vUpConvLength[maxNumSCVF]
convection length
Definition: upwind_interface.h:228
number upwind_conv_length(size_t scvf) const
Convection Length.
Definition: upwind_interface.h:89
number m_vvUpShapeSh[maxNumSCVF][maxNumSH]
upwind shapes for corners shape functions
Definition: upwind_interface.h:232
size_t m_numScvf
number of current scvf
Definition: upwind_interface.h:222
number & downwind_shape_ip(size_t scvf, size_t scvf2)
non-const access to upwind shapes for ip vel
Definition: upwind_interface.h:200
number upwind_shape_ip(size_t scvf, size_t scvf2) const
upwind shapes for ip vel
Definition: upwind_interface.h:127
number & upwind_shape_sh(size_t scvf, size_t sh)
non-const access to upwind shapes for corner vel
Definition: upwind_interface.h:176
fv1_dim_traits< dim, dim > traits
used traits
Definition: upwind_interface.h:60
number upwind_shape_sh(size_t scvf, size_t sh) const
upwind shape for corner vel
Definition: upwind_interface.h:108
void set_geometry_type()
set the Geometry type to use for next updates
Definition: upwind_interface.h:310
MathVector< dim > upwind_vel(const size_t scvf, const LocalVector &CornerVel, const MathVector< dim > vStdVel[]) const
returns the upwind velocity
Definition: upwind_interface.h:337
static const size_t maxNumSCVF
max number of SubControlVolumeFaces
Definition: upwind_interface.h:64
void update_upwind(const FVGeometryBase *geo, const MathVector< dim > vStdVel[])
compute values for new geometry and corner velocities
Definition: upwind_interface.h:150
bool non_zero_shape_ip() const
returns if upwind shape w.r.t. ip vel is non-zero
Definition: upwind_interface.h:124
number m_vvDownShapeIp[maxNumSCVF][maxNumSCVF]
Definition: upwind_interface.h:240
number & down_upwind_conv_length(size_t scvf)
non-const access to Convection Length
Definition: upwind_interface.h:215
Definition: upwind_interface.h:362
static const size_t maxNumSCVF
Definition: upwind_interface.h:368
void register_func(Int2Type< 3 >)
Definition: upwind_interface.h:387
INavierStokesUpwind< dim > base_type
Base class.
Definition: upwind_interface.h:365
NavierStokesUpwindRegister()
constructor
Definition: upwind_interface.h:373
void register_func(Int2Type< 2 >)
Definition: upwind_interface.h:381
void register_func(Int2Type< 1 >)
Definition: upwind_interface.h:376
void register_func()
Definition: upwind_interface.h:396
static const size_t maxNumSH
Definition: upwind_interface.h:369
TImpl & getImpl()
access to implementation
Definition: upwind_interface.h:412
static const int dim
#define UG_THROW(msg)
double number
void VecScaleAppend(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1)
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
SmartPtr< INavierStokesUpwind< dim > > CreateNavierStokesUpwind(const std::string &name)
creates upwind based on a string identifier
Definition: upwind_interface.cpp:44
void VecSet(vector_t &dest, number alpha, const std::vector< size_t > vIndex)
#define UG_NSUPWIND_ASSERT(cond, exp)
Definition: upwind_interface.h:38