GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/embedded/circlepoints.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 28 28 100.0%
Functions: 3 3 100.0%
Branches: 15 22 68.2%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup EmbeddedCoupling
10 * \brief Helper function to compute points on a circle
11 */
12
13 #ifndef DUMUX_MULTIDOMAIN_EMBEDDED_CIRCLEPOINTS_HH
14 #define DUMUX_MULTIDOMAIN_EMBEDDED_CIRCLEPOINTS_HH
15
16 #include <vector>
17 #include <cmath>
18
19 #include <dune/common/exceptions.hh>
20
21 #include <dumux/common/math.hh>
22 #include <dumux/geometry/normal.hh>
23
24 namespace Dumux::EmbeddedCoupling {
25
26 /*!
27 * \ingroup EmbeddedCoupling
28 * \param points a vector of points to be filled
29 * \param sincos vector with [sin(a0), cos(a0), sin(a1), cos(a1), ...] for each circumferential sample point ai
30 * \param center the circle center
31 * \param normal the normal to the circle plane
32 * \param radius the circle radius
33 * \note This version allows for a more efficient circle point generator
34 * if the circumferential positions are fixed and can be reused.
35 * In this case, sine and cosine of the corresponding angles can be precomputed.
36 */
37 template<class GlobalPosition, class Scalar>
38 46279 void circlePoints(std::vector<GlobalPosition>& points,
39 const std::vector<Scalar>& sincos,
40 const GlobalPosition& center,
41 const GlobalPosition& normal,
42 const Scalar radius)
43 {
44
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 46279 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46279 times.
92558 assert(sincos.size() % 2 == 0 && "Sample angles have to be pairs of sin/cos so size needs to be even.");
45 static_assert(GlobalPosition::dimension == 3, "Only implemented for world dimension 3");
46
47 // resize the points vector
48 46279 const std::size_t numPoints = sincos.size()/2;
49 46279 points.resize(numPoints);
50
51 // make sure n is a unit vector
52 46279 auto n = normal;
53 92558 n /= n.two_norm();
54
55 // calculate a vector u perpendicular to n
56 46279 auto u = unitNormal(n); u*= radius;
57
58 // the circle parameterization is p(t) = r*cos(t)*u + r*sin(t)*(n x u) + c
59 46279 auto tangent = crossProduct(u, n);
60 92558 tangent *= radius/tangent.two_norm();
61
62 // insert the vertices
63
2/2
✓ Branch 0 taken 3756998 times.
✓ Branch 1 taken 46279 times.
3803277 for (std::size_t i = 0; i < numPoints; ++i)
64 {
65 18784990 points[i] = GlobalPosition({u[0]*sincos[2*i+1] + tangent[0]*sincos[2*i] + center[0],
66 11270994 u[1]*sincos[2*i+1] + tangent[1]*sincos[2*i] + center[1],
67 15027992 u[2]*sincos[2*i+1] + tangent[2]*sincos[2*i] + center[2]});
68 }
69 46279 }
70
71 /*!
72 * \ingroup EmbeddedCoupling
73 * \brief returns a vector of sin and cos values of a circle parametrization
74 * \param numPoints the number of points
75 */
76 template<class Scalar = double>
77 22729 std::vector<Scalar> circlePointsSinCos(const std::size_t numPoints)
78 {
79 45458 std::vector<Scalar> sincos(2*numPoints);
80 22729 Scalar t = 0 + 0.1; // add arbitrary offset
81
2/2
✓ Branch 0 taken 319314 times.
✓ Branch 1 taken 22729 times.
342043 for (std::size_t i = 0; i < numPoints; ++i)
82 {
83 using std::sin; using std::cos;
84
2/2
✓ Branch 0 taken 22729 times.
✓ Branch 1 taken 296585 times.
319314 sincos[2*i] = sin(t);
85
2/2
✓ Branch 0 taken 22729 times.
✓ Branch 1 taken 296585 times.
319314 sincos[2*i + 1] = cos(t);
86 319314 t += 2*M_PI/numPoints;
87
2/2
✓ Branch 0 taken 22729 times.
✓ Branch 1 taken 296585 times.
319314 if(t > 2*M_PI) t -= 2*M_PI;
88 }
89 22729 return sincos;
90 }
91
92 /*!
93 * \ingroup EmbeddedCoupling
94 * \brief returns a vector of points on a circle
95 * \param center the circle center
96 * \param normal the normal to the circle plane
97 * \param radius the circle radius
98 * \param numPoints the number of points
99 */
100 template<class GlobalPosition, class Scalar>
101 22729 std::vector<GlobalPosition> circlePoints(const GlobalPosition& center,
102 const GlobalPosition& normal,
103 const Scalar radius,
104 const std::size_t numPoints = 20)
105 {
106 // precompute the sin/cos values
107
1/4
✓ Branch 1 taken 22729 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
45458 const auto sincos = circlePointsSinCos<Scalar>(numPoints);
108
109
1/2
✓ Branch 1 taken 22729 times.
✗ Branch 2 not taken.
22729 std::vector<GlobalPosition> points;
110
1/2
✓ Branch 1 taken 22729 times.
✗ Branch 2 not taken.
22729 circlePoints(points, sincos, center, normal, radius);
111 22729 return points;
112 }
113
114 } // end namespace Dumux::EmbeddedCoupling
115
116 #endif
117