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
40{
41
42RefRegionCylinder::RefRegionCylinder(const unsigned int coordim,
43 NekDouble radius,
44 std::vector<NekDouble> coord1,
45 std::vector<NekDouble> coord2,
46 std::vector<unsigned int> numModes,
47 std::vector<unsigned int> numPoints)
48 : RefRegion(coordim, radius, coord1, coord2, numModes, numPoints)
49{
50}
51
53{
54}
55
56/**
57 * @brief Check if vertex is inside the cylinder.
58 *
59 * @param coords coordinates of the vertex
60 * @return true or false depending on if the vertex is inside
61 * or not of the surface defined by the user.
62 */
64{
65 const size_t dim = coords.size();
66 Array<OneD, NekDouble> e(dim, 0.0); // direction: rb - ra
67 Array<OneD, NekDouble> m(dim, 0.0); // momentum: ra x rb
68 NekDouble d = 0.0; // distance
69
70 // Direction
71 e[0] = m_coord2[0] - m_coord1[0];
72 e[1] = m_coord2[1] - m_coord1[1];
73 e[2] = m_coord2[2] - m_coord1[2];
74
75 // Cross product of vectors 'coord1' and 'coord2'
76 m[0] = m_coord1[1] * m_coord2[2] - m_coord1[2] * m_coord2[1];
77 m[1] = m_coord1[2] * m_coord2[0] - m_coord1[0] * m_coord2[2];
78 m[2] = m_coord1[0] * m_coord2[1] - m_coord1[1] * m_coord2[0];
79
80 // 1. Distance of P (coords) to line AB (coord1coord2) is equal or less than
81 // R
82 // d = || e x (rp - ra) || / || e ||
83
84 // rA - rP
85 Array<OneD, NekDouble> rpa(dim, 0.0);
86 rpa[0] = coords[0] - m_coord1[0];
87 rpa[1] = coords[1] - m_coord1[1];
88 rpa[2] = coords[2] - m_coord1[2];
89
90 // || e ||
91 NekDouble e_mod = sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
92
93 // || e x (rp - ra) ||
94 Array<OneD, NekDouble> exrpa(dim, 0.0);
95 exrpa[0] = e[1] * rpa[2] - e[2] * rpa[1];
96 exrpa[1] = e[2] * rpa[0] - e[0] * rpa[2];
97 exrpa[2] = e[0] * rpa[1] - e[1] * rpa[0];
98
99 NekDouble exrpa_mod =
100 sqrt(exrpa[0] * exrpa[0] + exrpa[1] * exrpa[1] + exrpa[2] * exrpa[2]);
101
102 d = exrpa_mod / e_mod;
103 if (d >= m_radius)
104 {
105 return false;
106 }
107
108 // 2. Closest point Q on line AB to P
109 // rq = rp + (e x (m + e x rp)) / ||e||^{2}
110
111 // (m + e x rp)
112 Array<OneD, NekDouble> mpexrp(dim, 0.0);
113 mpexrp[0] = m[0] + e[1] * coords[2] - e[2] * coords[1];
114 mpexrp[1] = m[1] + e[2] * coords[0] - e[0] * coords[2];
115 mpexrp[2] = m[2] + e[0] * coords[1] - e[1] * coords[0];
116
117 // e x (m + e x rp) = numerator
118 Array<OneD, NekDouble> numerator(dim, 0.0);
119 numerator[0] = e[1] * mpexrp[2] - e[2] * mpexrp[1];
120 numerator[1] = e[2] * mpexrp[0] - e[0] * mpexrp[2];
121 numerator[2] = e[0] * mpexrp[1] - e[1] * mpexrp[0];
122
123 // rq
124 Array<OneD, NekDouble> rq(dim, 0.0);
125 rq[0] = coords[0] + (numerator[0] / pow(e_mod, 2));
126 rq[1] = coords[1] + (numerator[1] / pow(e_mod, 2));
127 rq[2] = coords[2] + (numerator[2] / pow(e_mod, 2));
128
129 // 3. The baricentric coordinates of Q(wa,wb) such that rq = wa*ra+wb*rb
130 // wa = ||rq x rb||/||m||, wb = ||rq x ra||/||m||
131 NekDouble wa = 0.0;
132 NekDouble wb = 0.0;
133
134 // ||m||
135 NekDouble m_mod = sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
136 // m_mod > 0: condition
137 ASSERTL0(m_mod, "The cylinder axis must not go through the origin");
138
139 // ||rq x rb||
140 Array<OneD, NekDouble> rqxrb(dim, 0.0);
141 rqxrb[0] = rq[1] * m_coord2[2] - rq[2] * m_coord2[1];
142 rqxrb[1] = rq[2] * m_coord2[0] - rq[0] * m_coord2[2];
143 rqxrb[2] = rq[0] * m_coord2[1] - rq[1] * m_coord2[0];
144 NekDouble rqxrb_mod =
145 sqrt(rqxrb[0] * rqxrb[0] + rqxrb[1] * rqxrb[1] + rqxrb[2] * rqxrb[2]);
146
147 // ||rq x ra||
148 Array<OneD, NekDouble> rqxra(dim, 0.0);
149 rqxra[0] = rq[1] * m_coord1[2] - rq[2] * m_coord1[1];
150 rqxra[1] = rq[2] * m_coord1[0] - rq[0] * m_coord1[2];
151 rqxra[2] = rq[0] * m_coord1[1] - rq[1] * m_coord1[0];
152 NekDouble rqxra_mod =
153 sqrt(rqxra[0] * rqxra[0] + rqxra[1] * rqxra[1] + rqxra[2] * rqxra[2]);
154
155 // wa
156 wa = rqxrb_mod / m_mod;
157 // wb
158 wb = rqxra_mod / m_mod;
159
160 // 4. Check that point Q between A and B by making sure the baricentric
161 // coordinates are between 0 and 1.
162 if ((wa >= 0) && (wa <= 1) && (wb >= 0) && (wb <= 1))
163 {
164 return true;
165 }
166 else
167 {
168 return false;
169 }
170}
171
172} // namespace Nektar::SpatialDomains
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
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:51
std::vector< NekDouble > m_coord2
Coordinate 2.
Definition: RefRegion.h:87
std::vector< NekDouble > m_coord1
Coordinate 1.
Definition: RefRegion.h:85
NekDouble m_radius
Radius of the surface region.
Definition: RefRegion.h:83
std::vector< double > d(NPUPPER *NPUPPER)
double NekDouble
STL namespace.
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294