Free Electron
TrianglePN.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __geometry_TrianglePN_h__
8 #define __geometry_TrianglePN_h__
9 
10 namespace fe
11 {
12 namespace ext
13 {
14 
15 /**************************************************************************//**
16  @brief Evaluate barycenter on triangle using Curved PN Triangles
17 
18  "Curved PN Triangles"
19  2001 Alex Vlachos, Jorg Peters, Chas Boyd, Jason L. Mitchell
20 
21  @ingroup geometry
22 *//***************************************************************************/
23 template <typename T>
25 {
26  public:
27  /// @brief halfway between two of the vertices
28  enum Edge
29  {
30  e_v1v2,
31  e_v2v3,
32  e_v3v1
33  };
34 
35  TrianglePN(void) {}
36 
37  void configure(const Vector<3,T>& v1,
38  const Vector<3,T>& v2,
39  const Vector<3,T>& v3,
40  const Vector<3,T>& n1,
41  const Vector<3,T>& n2,
42  const Vector<3,T>& n3);
43 
44  Vector<3,T> midpoint(Edge a_edge);
45  Vector<3,T> midnormal(Edge a_edge);
46 
47  void solve(const Barycenter<T>& barycenter,
48  Vector<3,T>& v,Vector<3,T>& n) const;
49 
50  private:
51  Vector<3,T> m_b300;
52  Vector<3,T> m_b030;
53  Vector<3,T> m_b003;
54  Vector<3,T> m_b210;
55  Vector<3,T> m_b120;
56  Vector<3,T> m_b021;
57  Vector<3,T> m_b012;
58  Vector<3,T> m_b102;
59  Vector<3,T> m_b201;
60  Vector<3,T> m_b111;
61 
62  Vector<3,T> m_n200;
63  Vector<3,T> m_n020;
64  Vector<3,T> m_n002;
65  Vector<3,T> m_n110;
66  Vector<3,T> m_n011;
67  Vector<3,T> m_n101;
68 
69 };
70 
71 template <typename T>
72 inline void TrianglePN<T>::configure(
73  const Vector<3,T>& v1,
74  const Vector<3,T>& v2,
75  const Vector<3,T>& v3,
76  const Vector<3,T>& n1,
77  const Vector<3,T>& n2,
78  const Vector<3,T>& n3)
79 {
80  if(isZero(n1) || isZero(n2) || isZero(n3))
81  {
82 #if FE_CODEGEN<=FE_DEBUG
83  feLog("v1 %s\n",c_print(v1));
84  feLog("v2 %s\n",c_print(v2));
85  feLog("v3 %s\n",c_print(v3));
86  feLog("n1 %s\n",c_print(n1));
87  feLog("n2 %s\n",c_print(n2));
88  feLog("n3 %s\n",c_print(n3));
89 #endif
90  feX(e_unsolvable,"TrianglePN<T>::configure","zero length normal(s)");
91  }
92 
93  m_b300=v1;
94  m_b030=v2;
95  m_b003=v3;
96 
97  const Vector<3,T> v2_v1=v2-v1;
98  const Vector<3,T> v3_v2=v3-v2;
99  const Vector<3,T> v1_v3=v1-v3;
100 
101  const T w12=dot(v2_v1,n1);
102  const T w21=dot(-v2_v1,n2);
103  const T w23=dot(v3_v2,n2);
104  const T w32=dot(-v3_v2,n3);
105  const T w31=dot(v1_v3,n3);
106  const T w13=dot(-v1_v3,n1);
107 
108  m_b210=(T(2)*v1+v2-w12*n1)*T(1.0/3.0);
109  m_b120=(T(2)*v2+v1-w21*n2)*T(1.0/3.0);
110  m_b021=(T(2)*v2+v3-w23*n2)*T(1.0/3.0);
111  m_b012=(T(2)*v3+v2-w32*n3)*T(1.0/3.0);
112  m_b102=(T(2)*v3+v1-w31*n3)*T(1.0/3.0);
113  m_b201=(T(2)*v1+v3-w13*n1)*T(1.0/3.0);
114 
115  const Vector<3,T> E=(m_b210+m_b120+m_b021+m_b012+m_b102+m_b201)*T(1.0/6.0);
116  const Vector<3,T> V=(v1+v2+v3)*T(1.0/3.0);
117  m_b111=E+(E-V)*T(1.0/2.0);
118 
119  m_n200=n1;
120  m_n020=n2;
121  m_n002=n3;
122 
123  const Vector<3,T> n1_n2=n1+n2;
124  const Vector<3,T> n2_n3=n2+n3;
125  const Vector<3,T> n3_n1=n3+n1;
126 
127  const T v12=T(2)*dot(v2_v1,n1_n2)/dot(v2_v1,v2_v1);
128  const T v23=T(2)*dot(v3_v2,n2_n3)/dot(v3_v2,v3_v2);
129  const T v31=T(2)*dot(v1_v3,n3_n1)/dot(v1_v3,v1_v3);
130 
131  const Vector<3,T> h110=n1_n2-v12*(v2_v1);
132  const Vector<3,T> h011=n2_n3-v23*(v3_v2);
133  const Vector<3,T> h101=n3_n1-v31*(v1_v3);
134 
135  m_n110=unit(h110);
136  m_n011=unit(h011);
137  m_n101=unit(h101);
138 }
139 
140 template <typename T>
141 inline void TrianglePN<T>::solve(
142  const Barycenter<T>& barycenter,
143  Vector<3,T>& vertex,Vector<3,T>& normal) const
144 {
145  const T u=barycenter[0];
146  const T v=barycenter[1];
147  const T w=1.0-u-v;
148 
149  const T uu=u*u;
150  const T vv=v*v;
151  const T ww=w*w;
152 
153  vertex=m_b300*uu*u+m_b030*vv*v+m_b003*ww*w+
154  T(3)*(m_b210*uu*v+m_b120*u*vv+m_b201*uu*w+
155  m_b021*vv*w+m_b102*u*ww+m_b012*v*ww)+
156  T(6)*m_b111*u*v*w;
157 
158  normal=unit(m_n200*uu+m_n020*vv+m_n002*ww+
159  m_n110*u*v+m_n011*v*w+m_n101*u*w);
160 }
161 
162 template <typename T>
164 {
165  switch(a_edge)
166  {
167  case e_v1v2:
168  return 0.125*(m_b300+m_b030+T(3)*(m_b210+m_b120));
169 
170  case e_v2v3:
171  return 0.125*(m_b030+m_b003+T(3)*(m_b021+m_b012));
172 
173  case e_v3v1:
174  return 0.125*(m_b300+m_b003+T(3)*(m_b201+m_b102));
175  }
176  return Vector<3,T>(0.0,0.0,0.0);
177 }
178 
179 template <typename T>
181 {
182  switch(a_edge)
183  {
184  case e_v1v2:
185  return unit(m_n200+m_n020+m_n110);
186 
187  case e_v2v3:
188  return unit(m_n020+m_n002+m_n011);
189 
190  case e_v3v1:
191  return unit(m_n200+m_n002+m_n101);
192  }
193  return Vector<3,T>(0.0,0.0,1.0);
194 }
195 
196 } /* namespace ext */
197 } /* namespace fe */
198 
199 #endif /* __geometry_TrianglePN_h__ */
200 
201 
kernel
Definition: namespace.dox:3
Evaluate barycenter on triangle using Curved PN Triangles.
Definition: TrianglePN.h:24
Barycentric coordinates for a triangle.
Definition: Barycenter.h:26
Edge
halfway between two of the vertices
Definition: TrianglePN.h:28