ug4
fv1_sss_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015: G-CSC, Goethe University Frankfurt
3  * Author: Michael Lampe
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 /*
34  * Singular sources and sinks for the FV discretizations: Implementation of the functions
35  */
36 
37 // ug4 headers
40 
41 namespace ug{
42 
49 template <int dim, typename TData>
50 template <typename TElem, typename TAAPos, typename TFVGeom>
52 (
53  TElem* elem,
54  Grid& grid,
55  TAAPos& aaPos,
56  const TFVGeom& geo,
57  size_t co
58 )
59 {
60 // restrict point to element
61  if (!ContainsPoint(elem, point, aaPos))
62  return false;
63 
64 // restrict point to scv
65  for (size_t i = 0; i < geo.num_scvf(); i++)
66  {
67  const typename TFVGeom::SCVF& scvf = geo.scvf(i);
69  VecSubtract(d, point, scvf.global_ip());
70  if (scvf.from() == co)
71  {
72  if (VecDot(d, scvf.normal()) >= 0.0)
73  return false;
74  }
75  else if (scvf.to() == co)
76  {
77  if (VecDot(d, scvf.normal()) < 0.0)
78  return false;
79  }
80  }
81  return true;
82 };
83 
95 template <int dim, typename TData>
96 template <typename TElem, typename TAAPos, typename TFVGeom>
98 (
99  TElem* elem,
100  Grid& grid,
101  TAAPos& aaPos,
102  const TFVGeom& geo,
103  size_t co,
104  MathVector<dim>& ls,
105  MathVector<dim>& le
106 )
107 {
108 // get the dimensionality of the element
109  int elem_dim = ReferenceElementDimension(elem->reference_object_id());
110 
111 // restrict line segment to element (so that ls and le are the intersection points with its sides)
112  ls = point1;
113  le = point2;
114  MathVector<dim> dir;
115  number lambda_min, lambda_max;
116  VecSubtract(dir, le, ls);
117  if (!RayElementIntersection(lambda_min, lambda_max, ls, dir, elem, grid, aaPos))
118  return false;
119 
120  if (elem_dim == dim) // full-dimensional element, two different points
121  {
122  // extend the ends of the segment to the sides of the element
123  if (ContainsPoint(elem, ls, aaPos))
124  lambda_min = 0.0;
125  if (ContainsPoint(elem, le, aaPos))
126  lambda_max = 1.0;
127 
128  // skip the segment if its line cuts the element before or after the segment
129  if (lambda_min < 0.0 || lambda_max > 1.0)
130  return false;
131 
132  // compute the corrected ends
133  VecScaleAdd(le, 1.0, ls, lambda_max, dir);
134  VecScaleAdd(ls, 1.0, ls, lambda_min, dir);
135 
136  // restrict line segment to scv (so that ls and le are the intersection points with the sides of the scv)
138  for (size_t i = 0; i < geo.num_scvf(); i++)
139  {
140  const typename TFVGeom::SCVF& scvf = geo.scvf(i);
141  number d_min, d_max, lambda;
142  if (scvf.from() == co)
143  {
144  VecSubtract(p, ls, scvf.global_ip());
145  d_min = VecDot(p, scvf.normal());
146  VecSubtract(p, le, scvf.global_ip());
147  d_max = VecDot(p, scvf.normal());
148  if (d_min*d_max < 0.0)
149  {
150  lambda = fabs(d_min)/(fabs(d_min)+fabs(d_max));
151  VecScaleAdd(p, 1.0-lambda, ls, lambda, le);
152  if (d_max > 0.0)
153  le = p;
154  else
155  ls = p;
156  }
157  else if (d_min > 0.0) // if so than d_max >= 0, too
158  return false;
159  }
160  else if (scvf.to() == co)
161  {
162  VecSubtract(p, ls, scvf.global_ip());
163  d_min = VecDot(p, scvf.normal());
164  VecSubtract(p, le, scvf.global_ip());
165  d_max = VecDot(p, scvf.normal());
166  if (d_min*d_max < 0.0)
167  {
168  lambda = fabs(d_min)/(fabs(d_min)+fabs(d_max));
169  VecScaleAdd(p, 1.0-lambda, ls, lambda, le);
170  if (d_max < 0.0)
171  le = p;
172  else
173  ls = p;
174  }
175  else if (d_min < 0.0) // if so than d_max <= 0, too
176  return false;
177  }
178  }
179  }
180  else if (elem_dim + 1 == dim) // low-dimensional element, we accept only one point
181  {
182  // skip the segment if its line cuts the element before or after the segment
183  if (lambda_min < 0.0 || lambda_max > 1.0)
184  return false;
185 
186  // exclude the case the the line in the plane
187  if (std::fabs (lambda_max - lambda_min) > SMALL)
188  UG_THROW ("FVLineSourceOrSink: Line source or sink lyes in a low-dimensional element!");
189 
190  // check if the point is in the scv
191  VecScaleAdd(ls, 1.0, point1, lambda_min, dir);
192  for (size_t i = 0; i < geo.num_scvf(); i++)
193  {
194  const typename TFVGeom::SCVF& scvf = geo.scvf(i);
195  MathVector<dim> d;
196  VecSubtract(d, ls, scvf.global_ip());
197  if (scvf.from() == co)
198  {
199  if (VecDot(d, scvf.normal()) > 0.0)
200  return false;
201  }
202  else if (scvf.to() == co)
203  {
204  if (VecDot(d, scvf.normal()) < 0.0)
205  return false;
206  }
207  }
208  le = ls;
209  }
210  else
211  UG_THROW ("FVLineSourceOrSink: Dimension mismatch with a grid element!");
212 
213  return true;
214 };
215 
219 template <int dim, typename TPointData, typename TLineData>
220 template <typename TElem, typename TAAPos, typename TFVGeom>
222 (
223  size_t index
224 )
225 {
226  for (m_index = index; m_index < m_sss->num_points (); m_index++)
227  {
228  point_sss_type * pnt_sss = m_sss->ListP[m_index].get();
229  if (! m_elem_bbox.contains_point (pnt_sss->position ())) // a quick test
230  continue;
231  if (pnt_sss->corresponds_to (m_elem, m_grid, m_aaPos, m_geo, m_co))
232  break;
233  }
234 };
235 
239 template <int dim, typename TPointData, typename TLineData>
240 template <typename TElem, typename TAAPos, typename TFVGeom>
242 (
243  size_t index,
244  MathVector<dim>& ls,
245  MathVector<dim>& le
246 )
247 {
248  for (m_index = index; m_index < m_sss->num_lines (); m_index++)
249  {
250  line_sss_type * line_sss = m_sss->ListL[m_index].get();
251  if (! m_elem_bbox.overlaps_line (line_sss->from_position (), line_sss->to_position ())) // a quick test
252  continue;
253  if (line_sss->corresponds_to (m_elem, m_grid, m_aaPos, m_geo, m_co, ls, le))
254  break;
255  }
256 };
257 
258 } // end of namespace ug
259 
260 /* End of File */
parameterString p
Base class for line sources and sinks.
Definition: fv1_sss.h:101
const MathVector< dim > & from_position()
returns the beginning of the line segment
Definition: fv1_sss.h:141
const MathVector< dim > & to_position()
returns the end of the line segment
Definition: fv1_sss.h:144
bool corresponds_to(TElem *elem, Grid &grid, TAAPos &aaPos, const TFVGeom &geo, size_t co, MathVector< dim > &ls, MathVector< dim > &le)
test whether a source/sink point corresponds to a given corner of the element
Definition: fv1_sss_impl.h:98
Base class for the point sources and sinks.
Definition: fv1_sss.h:51
bool corresponds_to(TElem *elem, Grid &grid, TAAPos &aaPos, const TFVGeom &geo, size_t co)
test whether a source/sink point corresponds to a given corner of the element
Definition: fv1_sss_impl.h:52
const MathVector< dim > & position()
returns the point of the source/sink
Definition: fv1_sss.h:84
Manager class for point and line sources and sinks.
Definition: fv1_sss.h:226
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
UG_API bool ContainsPoint(const EdgeVertices *e, const vector_t &p, TAAPos aaPos)
Returns true if the given point lies on the given edge.
Definition: edge_util_impl.hpp:513
static const int dim
#define UG_THROW(msg)
Definition: error.h:57
double number
Definition: types.h:124
void VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition: math_vector_functions_common_impl.hpp:265
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition: math_vector_functions_common_impl.hpp:226
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
returns the dot-product of two vector_ts
Definition: math_vector_functions_common_impl.hpp:385
the ug namespace
const number SMALL
Definition: math_constants.h:41
int ReferenceElementDimension(ReferenceObjectID roid)
returns the reference element dimension at run-time
Definition: reference_element_util.h:40
bool RayElementIntersection(number &sminOut, number &smaxOut, const vector2 &from, const vector2 &dir, Edge *e, Grid &, Grid::VertexAttachmentAccessor< AVector2 > aaPos, number sml)
2d ray-element intersection for edges
Definition: ray_element_intersection_util.cpp:83