Intrepid2
Intrepid2_OrientationToolsDefModifyPoints.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid2 Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Kyungjoo Kim (kyukim@sandia.gov), or
38 // Mauro Perego (mperego@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 
43 
48 #ifndef __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_POINTS_HPP__
49 #define __INTREPID2_ORIENTATIONTOOLS_DEF_MODIFY_POINTS_HPP__
50 
51 // disable clang warnings
52 #if defined (__clang__) && !defined (__INTEL_COMPILER)
53 #pragma clang system_header
54 #endif
55 
56 namespace Intrepid2 {
57 
58  namespace Impl {
59 
60  // ------------------------------------------------------------------------------------
61  // Modified points according to orientations
62  //
63  //
64  template<typename VT>
65  KOKKOS_INLINE_FUNCTION
66  void
69  const VT pt,
70  const ordinal_type ort) {
71 #ifdef HAVE_INTREPID2_DEBUG
72  INTREPID2_TEST_FOR_ABORT( !( -1.0 <= pt && pt <= 1.0 ),
73  ">>> ERROR (Intrepid::OrientationTools::getModifiedLinePoint): "
74  "Input point is out of range [-1, 1].");
75 #endif
76 
77  switch (ort) {
78  case 0: ot = pt; break;
79  case 1: ot = -pt; break;
80  default:
81  INTREPID2_TEST_FOR_ABORT( true,
82  ">>> ERROR (Intrepid2::OrientationTools::getModifiedLinePoint): "
83  "Orientation is invalid (0--1)." );
84  }
85  }
86 
87  template<typename JacobianViewType>
88  KOKKOS_INLINE_FUNCTION
89  void
91  getLineJacobian(JacobianViewType jacobian, const ordinal_type ort) {
92 #ifdef HAVE_INTREPID2_DEBUG
93  INTREPID2_TEST_FOR_ABORT( ort <0 || ort >1,
94  ">>> ERROR (Intrepid2::OrientationTools::getLineJacobian): " \
95  "Orientation is invalid (0--1)." );
96 #endif
97 
98  ordinal_type jac[2] = { 1, -1 };
99 
100  jacobian(0,0) = jac[ort];
101  }
102 
103  template<typename VT>
104  KOKKOS_INLINE_FUNCTION
105  void
108  VT &ot1,
109  const VT pt0,
110  const VT pt1,
111  const ordinal_type ort) {
112  const VT lambda[3] = { 1.0 - pt0 - pt1,
113  pt0,
114  pt1 };
115 
116 #ifdef HAVE_INTREPID2_DEBUG
117  VT eps = 10.0*std::numeric_limits<VT>::epsilon();
118  INTREPID2_TEST_FOR_ABORT( !( -eps <= lambda[0] && lambda[0] <= 1.0+eps ),
119  ">>> ERROR (Intrepid::OrientationTools::getModifiedTrianglePoint): " \
120  "Computed bicentric coordinate (lamba[0]) is out of range [0, 1].");
121 
122  INTREPID2_TEST_FOR_ABORT( !( -eps <= lambda[1] && lambda[1] <= 1.0+eps ),
123  ">>> ERROR (Intrepid::OrientationTools::getModifiedTrianglePoint): " \
124  "Computed bicentric coordinate (lamba[1]) is out of range [0, 1].");
125 
126  INTREPID2_TEST_FOR_ABORT( !( -eps <= lambda[2] && lambda[2] <= 1.0+eps ),
127  ">>> ERROR (Intrepid::OrientationTools::getModifiedTrianglePoint): "
128  "Computed bicentric coordinate (lamba[2]) is out of range [0, 1].");
129 #endif
130 
131  switch (ort) {
132  case 0: ot0 = lambda[1]; ot1 = lambda[2]; break;
133  case 1: ot0 = lambda[0]; ot1 = lambda[1]; break;
134  case 2: ot0 = lambda[2]; ot1 = lambda[0]; break;
135 
136  case 3: ot0 = lambda[2]; ot1 = lambda[1]; break;
137  case 4: ot0 = lambda[0]; ot1 = lambda[2]; break;
138  case 5: ot0 = lambda[1]; ot1 = lambda[0]; break;
139  default:
140  INTREPID2_TEST_FOR_ABORT( true,
141  ">>> ERROR (Intrepid2::OrientationTools::getModifiedTrianglePoint): " \
142  "Orientation is invalid (0--5)." );
143  }
144  }
145 
146  template<typename JacobianViewType>
147  KOKKOS_INLINE_FUNCTION
148  void
150  getTriangleJacobian(JacobianViewType jacobian, const ordinal_type ort) {
151 #ifdef HAVE_INTREPID2_DEBUG
152  INTREPID2_TEST_FOR_ABORT( ort <0 || ort >5,
153  ">>> ERROR (Intrepid2::OrientationTools::getTriangleJacobian): " \
154  "Orientation is invalid (0--5)." );
155 #endif
156 
157  ordinal_type jac[6][2][2] = { { { 1, 0 },
158  { 0, 1 } }, // 0
159  { { -1, -1 },
160  { 1, 0 } }, // 1
161  { { 0, 1 },
162  { -1, -1 } }, // 2
163  { { 0, 1 },
164  { 1, 0 } }, // 3
165  { { -1, -1 },
166  { 0, 1 } }, // 4
167  { { 1, 0 },
168  { -1, -1 } } }; // 5
169 
170  jacobian(0,0) = jac[ort][0][0];
171  jacobian(0,1) = jac[ort][0][1];
172  jacobian(1,0) = jac[ort][1][0];
173  jacobian(1,1) = jac[ort][1][1];
174  }
175 
176  template<typename VT>
177  KOKKOS_INLINE_FUNCTION
178  void
181  VT &ot1,
182  const VT pt0,
183  const VT pt1,
184  const ordinal_type ort) {
185 #ifdef HAVE_INTREPID2_DEBUG
186  INTREPID2_TEST_FOR_ABORT( !( -1.0 <= pt0 && pt0 <= 1.0 ),
187  ">>> ERROR (Intrepid::OrientationTools::getModifiedQuadrilateralPoint): " \
188  "Input point(0) is out of range [-1, 1].");
189 
190  INTREPID2_TEST_FOR_ABORT( !( -1.0 <= pt1 && pt1 <= 1.0 ),
191  ">>> ERROR (Intrepid::OrientationTools::getModifiedQuadrilateralPoint): " \
192  "Input point(1) is out of range [-1, 1].");
193 #endif
194 
195  const VT lambda[2][2] = { { pt0, -pt0 },
196  { pt1, -pt1 } };
197 
198  switch (ort) {
199  case 0: ot0 = lambda[0][0]; ot1 = lambda[1][0]; break;
200  case 1: ot0 = lambda[1][1]; ot1 = lambda[0][0]; break;
201  case 2: ot0 = lambda[0][1]; ot1 = lambda[1][1]; break;
202  case 3: ot0 = lambda[1][0]; ot1 = lambda[0][1]; break;
203  // flip
204  case 4: ot0 = lambda[1][0]; ot1 = lambda[0][0]; break;
205  case 5: ot0 = lambda[0][1]; ot1 = lambda[1][0]; break;
206  case 6: ot0 = lambda[1][1]; ot1 = lambda[0][1]; break;
207  case 7: ot0 = lambda[0][0]; ot1 = lambda[1][1]; break;
208  default:
209  INTREPID2_TEST_FOR_ABORT( true,
210  ">>> ERROR (Intrepid2::OrientationTools::getModifiedQuadrilateralPoint): " \
211  "Orientation is invalid (0--7)." );
212  }
213  }
214 
215  template<typename JacobianViewType>
216  KOKKOS_INLINE_FUNCTION
217  void
219  getQuadrilateralJacobian(JacobianViewType jacobian, const ordinal_type ort) {
220 #ifdef HAVE_INTREPID2_DEBUG
221  INTREPID2_TEST_FOR_ABORT( ort <0 || ort >7,
222  ">>> ERROR (Intrepid2::OrientationTools::getQuadrilateralJacobian): " \
223  "Orientation is invalid (0--7)." );
224 #endif
225 
226  ordinal_type jac[8][2][2] = { { { 1, 0 },
227  { 0, 1 } }, // 0
228  { { 0, -1 },
229  { 1, 0 } }, // 1
230  { { -1, 0 },
231  { 0, -1 } }, // 2
232  { { 0, 1 },
233  { -1, 0 } }, // 3
234  { { 0, 1 },
235  { 1, 0 } }, // 4
236  { { -1, 0 },
237  { 0, 1 } }, // 5
238  { { 0, -1 },
239  { -1, 0 } }, // 6
240  { { 1, 0 },
241  { 0, -1 } } }; // 7
242 
243  jacobian(0,0) = jac[ort][0][0];
244  jacobian(0,1) = jac[ort][0][1];
245  jacobian(1,0) = jac[ort][1][0];
246  jacobian(1,1) = jac[ort][1][1];
247  }
248 
249  template<typename outPointViewType,
250  typename refPointViewType>
251  inline
252  void
254  mapToModifiedReference(outPointViewType outPoints,
255  const refPointViewType refPoints,
256  const shards::CellTopology cellTopo,
257  const ordinal_type cellOrt) {
258 #ifdef HAVE_INTREPID2_DEBUG
259  {
260  const auto cellDim = cellTopo.getDimension();
261  INTREPID2_TEST_FOR_EXCEPTION( !( (1 <= cellDim) && (cellDim <= 2 ) ), std::invalid_argument,
262  ">>> ERROR (Intrepid::OrientationTools::mapToModifiedReference): " \
263  "Method defined only for 1 and 2-dimensional subcells.");
264 
265  INTREPID2_TEST_FOR_EXCEPTION( !( outPoints.extent(0) == refPoints.extent(0) ), std::invalid_argument,
266  ">>> ERROR (Intrepid::OrientationTools::mapToModifiedReference): " \
267  "Size of input and output point arrays does not match each other.");
268  }
269 #endif
270 
271  return mapToModifiedReference(outPoints, refPoints, cellTopo.getKey(), cellOrt);
272  }
273 
274 
275  template<typename outPointViewType,
276  typename refPointViewType>
277  inline
278  void
280  mapToModifiedReference(outPointViewType outPoints,
281  const refPointViewType refPoints,
282  const unsigned cellTopoKey,
283  const ordinal_type cellOrt) {
284  // Apply the parametrization map to every point in parameter domain
285  const ordinal_type numPts = outPoints.extent(0);
286  switch (cellTopoKey) {
287  case shards::Line<>::key : {
288  for (ordinal_type pt=0;pt<numPts;++pt)
289  getModifiedLinePoint(outPoints(pt, 0),
290  refPoints(pt, 0),
291  cellOrt);
292  break;
293  }
294  case shards::Triangle<>::key : {
295  for (ordinal_type pt=0;pt<numPts;++pt)
296  getModifiedTrianglePoint(outPoints(pt, 0), outPoints(pt, 1),
297  refPoints(pt, 0), refPoints(pt, 1),
298  cellOrt);
299  break;
300  }
301  case shards::Quadrilateral<>::key : {
302  for (ordinal_type pt=0;pt<numPts;++pt)
303  getModifiedQuadrilateralPoint(outPoints(pt, 0), outPoints(pt, 1),
304  refPoints(pt, 0), refPoints(pt, 1),
305  cellOrt);
306  break;
307  }
308  default: {
309  INTREPID2_TEST_FOR_ABORT( true,
310  ">>> ERROR (Intrepid2::OrientationTools::mapToModifiedReference): " \
311  "Invalid cell topology key." );
312  break;
313  }
314  }
315  }
316 
317 
318  template<typename outPointViewType>
319  inline
320  void
322  getJacobianOfOrientationMap(outPointViewType jacobian,
323  const shards::CellTopology cellTopo,
324  const ordinal_type cellOrt) {
325 #ifdef HAVE_INTREPID2_DEBUG
326  {
327  const auto cellDim = cellTopo.getDimension();
328  INTREPID2_TEST_FOR_EXCEPTION( !( (1 <= cellDim) && (cellDim <= 2 ) ), std::invalid_argument,
329  ">>> ERROR (Intrepid::OrientationTools::getJacobianOfOrientationMap): " \
330  "Method defined only for 1 and 2-dimensional subcells.");
331 
332  INTREPID2_TEST_FOR_ABORT( jacobian.rank() != 2,
333  ">>> ERROR (Intrepid2::OrientationTools::getJacobianOfOrientationMap): " \
334  "Jacobian should have rank 2" );
335 
336  INTREPID2_TEST_FOR_EXCEPTION( ((jacobian.extent(0) != cellDim) || (jacobian.extent(1) != cellDim)), std::invalid_argument,
337  ">>> ERROR (Intrepid::OrientationTools::getJacobianOfOrientationMap): " \
338  "Size of jacobian is not compatible with cell topology.");
339  }
340 #endif
341 
342  return getJacobianOfOrientationMap(jacobian, cellTopo.getKey(), cellOrt);
343  }
344 
345  template<typename outPointViewType>
346  inline
347  void
349  getJacobianOfOrientationMap(outPointViewType jacobian,
350  const unsigned cellTopoKey,
351  const ordinal_type cellOrt) {
352  switch (cellTopoKey) {
353  case shards::Line<>::key :
354  getLineJacobian(jacobian, cellOrt);
355  break;
356  case shards::Triangle<>::key :
357  getTriangleJacobian(jacobian, cellOrt);
358  break;
359  case shards::Quadrilateral<>::key :
360  getQuadrilateralJacobian(jacobian, cellOrt);
361  break;
362  default: {
363  INTREPID2_TEST_FOR_ABORT( true,
364  ">>> ERROR (Intrepid2::OrientationTools::mapToModifiedReference): " \
365  "Invalid cell topology key." );
366  break;
367  }
368  }
369  }
370 
371 
372 
373  }
374 }
375 
376 #endif
static KOKKOS_INLINE_FUNCTION void getModifiedLinePoint(ValueType &ot, const ValueType pt, const ordinal_type ort)
Computes modified point for line segment.
static KOKKOS_INLINE_FUNCTION void getModifiedQuadrilateralPoint(ValueType &ot0, ValueType &ot1, const ValueType pt0, const ValueType pt1, const ordinal_type ort)
Computes modified point for quadrilateral.
static void getJacobianOfOrientationMap(JacobianViewType jacobian, const shards::CellTopology cellTopo, const ordinal_type cellOrt)
Computes jacobian of the parameterization maps of 1- and 2-subcells with orientation.
static KOKKOS_INLINE_FUNCTION void getModifiedTrianglePoint(ValueType &ot0, ValueType &ot1, const ValueType pt0, const ValueType pt1, const ordinal_type ort)
Computes modified point for triangle.
static KOKKOS_INLINE_FUNCTION void getTriangleJacobian(JacobianViewType jacobian, const ordinal_type ort)
Computes Jacobian of orientation map for triangle.
static KOKKOS_INLINE_FUNCTION void getLineJacobian(JacobianViewType jacobian, const ordinal_type ort)
Computes Jacobian of orientation map for line segment.
static KOKKOS_INLINE_FUNCTION void getQuadrilateralJacobian(JacobianViewType jacobian, const ordinal_type ort)
Computes Jacobian of orientation map for quadrilateral.
static void mapToModifiedReference(outPointViewType outPoints, const refPointViewType refPoints, const shards::CellTopology cellTopo, const ordinal_type cellOrt=0)
Computes modified parameterization maps of 1- and 2-subcells with orientation.