Nektar++
RefRegionCylinder.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: RefRegionCylinder.cpp
4//
5// For more information, please see: http://www.nektar.info/
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Cylindrical surface for the refinement region.
32//
33////////////////////////////////////////////////////////////////////////////////
34
36
37using namespace std;
38
39namespace Nektar
40{
41namespace SpatialDomains
42{
43
44RefRegionCylinder::RefRegionCylinder(const unsigned int coordim,
45 NekDouble radius,
46 std::vector<NekDouble> coord1,
47 std::vector<NekDouble> coord2,
48 std::vector<unsigned int> numModes,
49 std::vector<unsigned int> numPoints)
50 : RefRegion(coordim, radius, coord1, coord2, numModes, numPoints)
51{
52}
53
55{
56}
57
58/**
59 * @brief Check if vertex is inside the cylinder.
60 *
61 * @param coords coordinates of the vertex
62 * @return true or false depending on if the vertex is inside
63 * or not of the surface defined by the user.
64 */
66{
67 const size_t dim = coords.size();
68 Array<OneD, NekDouble> e(dim, 0.0); // direction: rb - ra
69 Array<OneD, NekDouble> m(dim, 0.0); // momentum: ra x rb
70 NekDouble d = 0.0; // distance
71
72 // Direction
73 e[0] = m_coord2[0] - m_coord1[0];
74 e[1] = m_coord2[1] - m_coord1[1];
75 e[2] = m_coord2[2] - m_coord1[2];
76
77 // Cross product of vectors 'coord1' and 'coord2'
78 m[0] = m_coord1[1] * m_coord2[2] - m_coord1[2] * m_coord2[1];
79 m[1] = m_coord1[2] * m_coord2[0] - m_coord1[0] * m_coord2[2];
80 m[2] = m_coord1[0] * m_coord2[1] - m_coord1[1] * m_coord2[0];
81
82 // 1. Distance of P (coords) to line AB (coord1coord2) is equal or less than
83 // R
84 // d = || e x (rp - ra) || / || e ||
85
86 // rA - rP
87 Array<OneD, NekDouble> rpa(dim, 0.0);
88 rpa[0] = coords[0] - m_coord1[0];
89 rpa[1] = coords[1] - m_coord1[1];
90 rpa[2] = coords[2] - m_coord1[2];
91
92 // || e ||
93 NekDouble e_mod = sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
94
95 // || e x (rp - ra) ||
96 Array<OneD, NekDouble> exrpa(dim, 0.0);
97 exrpa[0] = e[1] * rpa[2] - e[2] * rpa[1];
98 exrpa[1] = e[2] * rpa[0] - e[0] * rpa[2];
99 exrpa[2] = e[0] * rpa[1] - e[1] * rpa[0];
100
101 NekDouble exrpa_mod =
102 sqrt(exrpa[0] * exrpa[0] + exrpa[1] * exrpa[1] + exrpa[2] * exrpa[2]);
103
104 d = exrpa_mod / e_mod;
105 if (d >= m_radius)
106 {
107 return false;
108 }
109
110 // 2. Closest point Q on line AB to P
111 // rq = rp + (e x (m + e x rp)) / ||e||^{2}
112
113 // (m + e x rp)
114 Array<OneD, NekDouble> mpexrp(dim, 0.0);
115 mpexrp[0] = m[0] + e[1] * coords[2] - e[2] * coords[1];
116 mpexrp[1] = m[1] + e[2] * coords[0] - e[0] * coords[2];
117 mpexrp[2] = m[2] + e[0] * coords[1] - e[1] * coords[0];
118
119 // e x (m + e x rp) = numerator
120 Array<OneD, NekDouble> numerator(dim, 0.0);
121 numerator[0] = e[1] * mpexrp[2] - e[2] * mpexrp[1];
122 numerator[1] = e[2] * mpexrp[0] - e[0] * mpexrp[2];
123 numerator[2] = e[0] * mpexrp[1] - e[1] * mpexrp[0];
124
125 // rq
126 Array<OneD, NekDouble> rq(dim, 0.0);
127 rq[0] = coords[0] + (numerator[0] / pow(e_mod, 2));
128 rq[1] = coords[1] + (numerator[1] / pow(e_mod, 2));
129 rq[2] = coords[2] + (numerator[2] / pow(e_mod, 2));
130
131 // 3. The baricentric coordinates of Q(wa,wb) such that rq = wa*ra+wb*rb
132 // wa = ||rq x rb||/||m||, wb = ||rq x ra||/||m||
133 NekDouble wa = 0.0;
134 NekDouble wb = 0.0;
135
136 // ||m||
137 NekDouble m_mod = sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
138 // m_mod > 0: condition
139 ASSERTL0(m_mod, "The cylinder axis must not go through the origin");
140
141 // ||rq x rb||
142 Array<OneD, NekDouble> rqxrb(dim, 0.0);
143 rqxrb[0] = rq[1] * m_coord2[2] - rq[2] * m_coord2[1];
144 rqxrb[1] = rq[2] * m_coord2[0] - rq[0] * m_coord2[2];
145 rqxrb[2] = rq[0] * m_coord2[1] - rq[1] * m_coord2[0];
146 NekDouble rqxrb_mod =
147 sqrt(rqxrb[0] * rqxrb[0] + rqxrb[1] * rqxrb[1] + rqxrb[2] * rqxrb[2]);
148
149 // ||rq x ra||
150 Array<OneD, NekDouble> rqxra(dim, 0.0);
151 rqxra[0] = rq[1] * m_coord1[2] - rq[2] * m_coord1[1];
152 rqxra[1] = rq[2] * m_coord1[0] - rq[0] * m_coord1[2];
153 rqxra[2] = rq[0] * m_coord1[1] - rq[1] * m_coord1[0];
154 NekDouble rqxra_mod =
155 sqrt(rqxra[0] * rqxra[0] + rqxra[1] * rqxra[1] + rqxra[2] * rqxra[2]);
156
157 // wa
158 wa = rqxrb_mod / m_mod;
159 // wb
160 wb = rqxra_mod / m_mod;
161
162 // 4. Check that point Q between A and B by making sure the baricentric
163 // coordinates are between 0 and 1.
164 if ((wa >= 0) && (wa <= 1) && (wb >= 0) && (wb <= 1))
165 {
166 return true;
167 }
168 else
169 {
170 return false;
171 }
172}
173
174} // namespace SpatialDomains
175} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
bool v_Contains(const Array< OneD, NekDouble > &coords) override
Check if vertex is inside the surface region.
RefRegionCylinder(const unsigned int coordim, NekDouble radius, std::vector< NekDouble > coord1, std::vector< NekDouble > coord2, std::vector< unsigned int > numModes, std::vector< unsigned int > numPoints)
Constructor.
Abstract base class for the refinement surface region.
Definition: RefRegion.h:53
std::vector< NekDouble > m_coord2
Coordinate 2.
Definition: RefRegion.h:89
std::vector< NekDouble > m_coord1
Coordinate 1.
Definition: RefRegion.h:87
NekDouble m_radius
Radius of the surface region.
Definition: RefRegion.h:85
std::vector< double > d(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294