FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
details.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// This file defines detail implementations as templated functions.
9// This is mainly done due to avoid code duplication for the voxel assembly.
10// \author Maximilian Esser, Peter Zajac
11
13#include <kernel/shape.hpp>
14#include <kernel/util/tiny_algebra.hpp>
15#ifndef __CUDA_ARCH__
16#include <kernel/util/math.hpp>
17#else
18#include <kernel/util/cuda_math.cuh>
19#endif
20
21namespace FEAT
22{
23 namespace Trafo
24 {
25 namespace Standard
26 {
46 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
47 typename HessType_, typename HessInvType_, typename Shape_, int img_dim>
48 struct EvalHelper;
49
50
51 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
52 typename HessType_, typename HessInvType_, int img_dim>
53 struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Simplex<1>, img_dim>
54 {
56 typedef DataType_ DataType;
58 typedef DomPointType_ DomainPointType;
60 typedef ImgPointType_ ImagePointType;
62 typedef JacMatType_ JacobianMatrixType;
64 typedef JacMatInvType_ JacobianInverseType;
66 typedef JacDetType_ JacobianDeterminantType;
68 typedef HessType_ HessianTensorType;
70 typedef HessInvType_ HessianInverseType;
73
74 static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
75 static constexpr int image_dim = img_dim;
76
92 template<typename VertexSetType_, typename IndexSetType_, typename IT_>
93 CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, image_dim, num_verts>& coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, IT_ cell_index)
94 {
95 typedef typename VertexSetType_::VertexType VertexType;
96
97 const VertexType& v0 = vertex_set[index_set(cell_index, 0)];
98 const VertexType& v1 = vertex_set[index_set(cell_index, 1)];
99
100
101 for(int i(0); i < image_dim; ++i)
102 {
103 coeffs[i][0] = DataType(v0[i]);
104 coeffs[i][1] = DataType(v1[i] - v0[i]);
105 }
106
107 }
108
122 {
123 for(int i(0); i < image_dim; ++i)
124 {
125 img_point[i] = coeffs[i][0] + coeffs[i][1] * dom_point[0];
126 }
127 }
128
141 CUDA_HOST_DEVICE static inline void calc_jac_mat(JacobianMatrixType& jac_mat, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
142 {
143 for(int i(0); i < img_dim; ++i)
144 {
145 jac_mat(i,0) = coeffs[i][1];
146 }
147 }
148
161 CUDA_HOST_DEVICE static inline void calc_hess_ten(HessianTensorType& hess_ten, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
162 {
163 hess_ten.format();
164 }
165
175 CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
176 {
177 DataType v = DataType(0);
178 #ifndef __CUDA_ARCH__
179 for(int i(0); i < image_dim; ++i)
180 v += Math::sqr(coeffs[i][1]);
181 return Math::sqrt(v);
182 #else
183 for(int i(0); i < image_dim; ++i)
184 v += CudaMath::cuda_sqr(coeffs[i][1]);
185 return CudaMath::cuda_sqrt(v);
186 #endif
187 }
188
203 CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& DOXY(ray), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
204 {
205 // in 1D, the width is always equal to the volume
206 return volume(coeffs);
207 }
208 }; // EvalHelper<Simplex<1>,...>
209
210 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
211 typename HessType_, typename HessInvType_, int img_dim>
212 struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Simplex<2>, img_dim>
213 {
215 typedef DataType_ DataType;
217 typedef DomPointType_ DomainPointType;
219 typedef ImgPointType_ ImagePointType;
221 typedef JacMatType_ JacobianMatrixType;
223 typedef JacMatInvType_ JacobianInverseType;
225 typedef JacDetType_ JacobianDeterminantType;
227 typedef HessType_ HessianTensorType;
229 typedef HessInvType_ HessianInverseType;
232
233 static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
234 static constexpr int image_dim = img_dim;
235
252 template<typename VertexSetType_, typename IndexSetType_, typename IT_>
253 CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, image_dim, num_verts>& coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, IT_ cell_index)
254 {
255 typedef typename VertexSetType_::VertexType VertexType;
256
257 const VertexType& v0 = vertex_set[index_set(cell_index, 0)];
258 const VertexType& v1 = vertex_set[index_set(cell_index, 1)];
259 const VertexType& v2 = vertex_set[index_set(cell_index, 2)];
260
261 // calculate transformation coefficients
262 for(int i(0); i < image_dim; ++i)
263 {
264 coeffs[i][0] = DataType(v0[i]);
265 coeffs[i][1] = DataType(v1[i] - v0[i]);
266 coeffs[i][2] = DataType(v2[i] - v0[i]);
267 }
268
269 }
270
284 {
285 for(int i(0); i < image_dim; ++i)
286 {
287 img_point[i] = coeffs[i][0] + coeffs[i][1] * dom_point[0] + coeffs[i][2] * dom_point[1];
288 }
289 }
290
303 CUDA_HOST_DEVICE static inline void calc_jac_mat(JacobianMatrixType& jac_mat, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
304 {
305 for(int i(0); i < image_dim; ++i)
306 {
307 jac_mat(i,0) = coeffs[i][1];
308 jac_mat(i,1) = coeffs[i][2];
309 }
310 }
311
324 CUDA_HOST_DEVICE static inline void calc_hess_ten(HessianTensorType& hess_ten, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
325 {
326 hess_ten.format();
327 }
328
338 CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
339 {
341 for(int i(0); i < image_dim; ++i)
342 {
343 jac_mat(i,0) = coeffs[i][1];
344 jac_mat(i,1) = coeffs[i][2];
345 }
346 return jac_mat.vol() / DataType(2);
347 }
348
363 CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& ray, const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
364 {
365 // This one is a little tricky:
366 // We follow a similar approach as on quadrilaterals here, i.e. we first map the ray
367 // vector onto the reference cells by multiplying it to the inverse jacobian matrix.
368 // However, our reference cell is the "right triangle" spanned by the three points
369 // (0,0) (1,0) (0,1) and therefore its edges have different lengths, which would
370 // result in a "skew" width. To circumvent this, we will afterwards map the ray
371 // vector onto a "equilateral unit triangle" (i.e. the triangle where all edges
372 // have length = 1) and we compute the norm of that mapped vector then.
375 DomainPointType ref_ray;
376
377 // compute jacobian matrix
378 for(int i(0); i < image_dim; ++i)
379 {
380 jac_mat(i,0) = coeffs[i][1];
381 jac_mat(i,1) = coeffs[i][2];
382 }
383
384 // invert jacobian matrix and multiply by ray vector
385 jac_inv.set_inverse(jac_mat);
386 ref_ray.set_mat_vec_mult(jac_inv, ray);
387
388 // We have mapped the ray onto our reference triangle. Now let's map that one
389 // onto a equilateral unit triangle, which can be performed by multiplying
390 // the following matrix by the reference ray vector:
391 //
392 // eut_ray := [ -1 +1 ] * ref_ray
393 // [ sqrt(3) sqrt(3) ]
394 //
395 // Finally, we have to compute the norm of that vector, which is explicitly
396 // written down in the denominator of the following expression:
397 #ifndef __CUDA_ARCH__
398 return DataType(2) / Math::sqrt(Math::sqr(ref_ray[1]-ref_ray[0]) + DataType(3) * Math::sqr(ref_ray[0]+ref_ray[1]));
399 #else
400 return DataType(2) * CudaMath::cuda_rsqrt(Math::sqr(ref_ray[1]-ref_ray[0]) + DataType(3) * Math::sqr(ref_ray[0]+ref_ray[1]));
401 #endif
402 }
403 }; // EvalHelper<Simplex<2>,...>
404
405 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
406 typename HessType_, typename HessInvType_, int img_dim>
407 struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Simplex<3>, img_dim>
408 {
410 typedef DataType_ DataType;
412 typedef DomPointType_ DomainPointType;
414 typedef ImgPointType_ ImagePointType;
416 typedef JacMatType_ JacobianMatrixType;
418 typedef JacMatInvType_ JacobianInverseType;
420 typedef JacDetType_ JacobianDeterminantType;
422 typedef HessType_ HessianTensorType;
424 typedef HessInvType_ HessianInverseType;
427
428 static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
429 static constexpr int image_dim = img_dim;
430
446 template<typename VertexSetType_, typename IndexSetType_, typename IT_>
447 CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, image_dim, num_verts>& coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, IT_ cell_index)
448 {
449 // fetch the vertices of the edge
450 typedef typename VertexSetType_::VertexType VertexType;
451 const VertexType& v0 = vertex_set[index_set(cell_index, 0)];
452 const VertexType& v1 = vertex_set[index_set(cell_index, 1)];
453 const VertexType& v2 = vertex_set[index_set(cell_index, 2)];
454 const VertexType& v3 = vertex_set[index_set(cell_index, 3)];
455
456 // calculate transformation coefficients
457 for(int i(0); i < image_dim; ++i)
458 {
459 coeffs[i][0] = DataType(v0[i]);
460 coeffs[i][1] = DataType(v1[i] - v0[i]);
461 coeffs[i][2] = DataType(v2[i] - v0[i]);
462 coeffs[i][3] = DataType(v3[i] - v0[i]);
463 }
464
465 }
466
480 {
481 for(int i(0); i < image_dim; ++i)
482 {
483 img_point[i] = coeffs[i][0] + coeffs[i][1] * dom_point[0]
484 + coeffs[i][2] * dom_point[1]
485 + coeffs[i][3] * dom_point[2];
486 }
487 }
488
501 CUDA_HOST_DEVICE static inline void calc_jac_mat(JacobianMatrixType& jac_mat, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
502 {
503 for(int i(0); i < image_dim; ++i)
504 {
505 jac_mat(i,0) = coeffs[i][1];
506 jac_mat(i,1) = coeffs[i][2];
507 jac_mat(i,2) = coeffs[i][3];
508 }
509 }
510
523 CUDA_HOST_DEVICE static inline void calc_hess_ten(HessianTensorType& hess_ten, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
524 {
525 hess_ten.format();
526 }
527
537 CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
538 {
540 for(int i(0); i < image_dim; ++i)
541 {
542 jac_mat(i,0) = coeffs[i][1];
543 jac_mat(i,1) = coeffs[i][2];
544 jac_mat(i,2) = coeffs[i][3];
545 }
546 return jac_mat.vol() / DataType(6);
547 }
548
563 CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& ray, const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
564 {
565 // We follow the same approach as for triangles here:
566 // First, map the ray onto the reference element and then
567 // map it to a regular tetrahedron to compute its norm.
570 DomainPointType ref_ray;
571
572 // compute jacobian matrix
573 for(int i(0); i < image_dim; ++i)
574 {
575 jac_mat(i,0) = coeffs[i][1];
576 jac_mat(i,1) = coeffs[i][2];
577 jac_mat(i,2) = coeffs[i][3];
578 }
579
580 // invert jacobian matrix and multiply by ray vector
581 jac_inv.set_inverse(jac_mat);
582 ref_ray.set_mat_vec_mult(jac_inv, ray);
583
584 // The transformation from the reference tetrahedron to the regular unit tetrahedron
585 // can be performed by applying the following matrix-vector product:
586 //
587 // [ 2 1 1 ]
588 // eut_ray := [ 0 1 -1 ] * ref_ray
589 // [ 0 sqrt(2) sqrt(2) ]
590 //
591 // Finally, we have to compute the norm of that vector, which is explicitly
592 // written down in the denominator of the following expression:
593 #ifndef __CUDA_ARCH__
594 return DataType(2) / Math::sqrt(Math::sqr(DataType(2) * ref_ray[0] + ref_ray[1] + ref_ray[2]) +
595 Math::sqr(ref_ray[1] - ref_ray[2]) + DataType(2) * Math::sqr(ref_ray[1] + ref_ray[2]));
596 #else
597 return DataType(2) * CudaMath::cuda_rsqrt(CudaMath::sqr(DataType(2) * ref_ray[0] + ref_ray[1] + ref_ray[2]) +
598 CudaMath::cuda_sqr(ref_ray[1] - ref_ray[2]) + DataType(2) * CudaMath::cuda_sqr(ref_ray[1] + ref_ray[2]));
599 #endif
600 }
601 }; // EvalHelper<Simplex<3>,...>
602
603 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
604 typename HessType_, typename HessInvType_, int img_dim>
605 struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Hypercube<1>, img_dim>
606 {
608 typedef DataType_ DataType;
610 typedef DomPointType_ DomainPointType;
612 typedef ImgPointType_ ImagePointType;
614 typedef JacMatType_ JacobianMatrixType;
616 typedef JacMatInvType_ JacobianInverseType;
618 typedef JacDetType_ JacobianDeterminantType;
620 typedef HessType_ HessianTensorType;
622 typedef HessInvType_ HessianInverseType;
625
626 static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
627 static constexpr int image_dim = img_dim;
628
644 template<typename VertexSetType_, typename IndexSetType_, typename IT_>
645 CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, image_dim, num_verts>& coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, IT_ cell_index)
646 {
647 typedef typename VertexSetType_::VertexType VertexType;
648
649 const VertexType& v0 = vertex_set[index_set(cell_index, 0)];
650 const VertexType& v1 = vertex_set[index_set(cell_index, 1)];
651
652
653 for(int i(0); i < img_dim; ++i)
654 {
655 coeffs[i][0] = DataType(0.5) * DataType( v0[i] + v1[i]);
656 coeffs[i][1] = DataType(0.5) * DataType(-v0[i] + v1[i]);
657 }
658
659 }
660
674 {
675 for(int i(0); i < image_dim; ++i)
676 {
677 img_point[i] = coeffs[i][0] + coeffs[i][1] * dom_point[0];
678 }
679 }
680
693 CUDA_HOST_DEVICE static inline void calc_jac_mat(JacobianMatrixType& jac_mat, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
694 {
695 for(int i(0); i < img_dim; ++i)
696 {
697 jac_mat(i,0) = coeffs[i][1];
698 }
699 }
700
713 CUDA_HOST_DEVICE static inline void calc_hess_ten(HessianTensorType& hess_ten, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
714 {
715 hess_ten.format();
716 }
717
727 CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
728 {
729 DataType v = DataType(0);
730 #ifndef __CUDA_ARCH__
731 for(int i(0); i < image_dim; ++i)
732 v += Math::sqr(coeffs[i][1]);
733 return DataType(2) * Math::sqrt(v);
734 #else
735 for(int i(0); i < image_dim; ++i)
736 v += CudaMath::cuda_sqr(coeffs[i][1]);
737 return DataType(2) * CudaMath::cuda_sqrt(v);
738 #endif
739 }
740
755 CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& DOXY(ray), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
756 {
757 // in 1D, the width is always equal to the volume
758 return volume(coeffs);
759 }
760 }; // EvalHelper<Hypercube<1>,...>
761
762 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
763 typename HessType_, typename HessInvType_, int img_dim>
764 struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Hypercube<2>, img_dim>
765 {
767 typedef DataType_ DataType;
769 typedef DomPointType_ DomainPointType;
771 typedef ImgPointType_ ImagePointType;
773 typedef JacMatType_ JacobianMatrixType;
775 typedef JacMatInvType_ JacobianInverseType;
777 typedef JacDetType_ JacobianDeterminantType;
779 typedef HessType_ HessianTensorType;
781 typedef HessInvType_ HessianInverseType;
784
785 static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
786 static constexpr int image_dim = img_dim;
787
803 template<typename VertexSetType_, typename IndexSetType_, typename IT_>
804 CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, image_dim, num_verts>& coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, IT_ cell_index)
805 {
806 typedef typename VertexSetType_::VertexType VertexType;
807
808 const VertexType& v0 = vertex_set[index_set(cell_index, 0)];
809 const VertexType& v1 = vertex_set[index_set(cell_index, 1)];
810 const VertexType& v2 = vertex_set[index_set(cell_index, 2)];
811 const VertexType& v3 = vertex_set[index_set(cell_index, 3)];
812
813 // calculate transformation coefficients
814 for(int i(0); i < image_dim; ++i)
815 {
816 coeffs[i][0] = DataType(0.25) * DataType( v0[i] + v1[i] + v2[i] + v3[i]);
817 coeffs[i][1] = DataType(0.25) * DataType(-v0[i] + v1[i] - v2[i] + v3[i]);
818 coeffs[i][2] = DataType(0.25) * DataType(-v0[i] - v1[i] + v2[i] + v3[i]);
819 coeffs[i][3] = DataType(0.25) * DataType( v0[i] - v1[i] - v2[i] + v3[i]);
820 }
821
822 // #ifndef __CUDACC__
823 // for(int i(0); i < image_dim; ++i)
824 // {
825 // for(int k(0); k < 4; ++k)
826 // {
827 // std::cout << "coeff i, k " << i << ", " << k << " " << coeffs[i][k] << "\n";
828 // }
829 // }
830 // #endif
831
832 }
833
834 #ifdef __CUDACC__
835 template<typename ThreadGroup_, typename VertexSetType_, typename IndexSetType_>
836 CUDA_DEVICE static void __forceinline__ _group_gather_vertex_set(const ThreadGroup_& tg, typename VertexSetType_::VertexType* __restrict__ vn, const VertexSetType_& vertex_set, const IndexSetType_& index_set, const Index cell_index)
837 {
838 // use block strided access pattern
839 for(int i = tg.thread_rank(); i < num_verts; i += tg.num_threads())
840 vn[i] = vertex_set[index_set(cell_index, i)];
841 }
842
843 template<typename ThreadGroup_, typename VertexType_>
844 CUDA_DEVICE static void __forceinline__ _group_set_coeffs(const ThreadGroup_& tg, DataType* __restrict__ coeffs, const VertexType_* __restrict__ vn)
845 {
846 // calculate transformation coefficients
847 // j = _coeff[i][j] for all j = 0....7
848 // v = 0 + 1*x + 2*y + 3*z + x*y*4 + x*z*5 + y*z*6 + x*y*z*7
849 // there is simply no nice way to do this... still, it seems directly transmitting the coeffs could be more efficient...
850 for(int i = tg.thread_rank(); i < image_dim; i += tg.num_threads())
851 {
852 coeffs[4*i+0] = DataType(0.25) * DataType( vn[0][i] + vn[1][i] + vn[2][i] + vn[3][i]);
853 coeffs[4*i+1] = DataType(0.25) * DataType(-vn[0][i] + vn[1][i] - vn[2][i] + vn[3][i]);
854 coeffs[4*i+2] = DataType(0.25) * DataType(-vn[0][i] - vn[1][i] + vn[2][i] + vn[3][i]);
855 coeffs[4*i+3] = DataType(0.25) * DataType( vn[0][i] - vn[1][i] - vn[2][i] + vn[3][i]);
856 }
857 }
878 template<typename ThreadGroup_, typename VertexSetType_, typename IndexSetType_, typename IT_>
879 CUDA_DEVICE static void inline grouped_set_coefficients(const ThreadGroup_& tg, DataType* coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, const IT_ cell_index)
880 {
881 typedef typename VertexSetType_::VertexType VertexType;
882 // get shared vertex set array
883 __shared__ VertexType vn[8];
884
885 _group_gather_vertex_set(tg, vn, vertex_set, index_set, cell_index);
886
887 tg.sync();
888
889 _group_set_coeffs(tg, coeffs, vn);
890
891 tg.sync();
892 }
893 #endif
894
908 {
909 for(int i(0); i < image_dim; ++i)
910 {
911 img_point[i] = coeffs[i][0] + coeffs[i][1] * dom_point[0] +
912 (coeffs[i][2] + coeffs[i][3] * dom_point[0]) * dom_point[1];
913 }
914 }
915
929 {
930 for(int i(0); i < image_dim; ++i)
931 {
932 jac_mat(i,0) = coeffs[i][1] + dom_point[1] * coeffs[i][3];
933 jac_mat(i,1) = coeffs[i][2] + dom_point[0] * coeffs[i][3];
934 }
935 }
936
937 #ifdef __CUDACC__
957 template<typename ThreadGroup_>
958 CUDA_DEVICE static inline void grouped_calc_jac_mat(const ThreadGroup_& tg, JacobianMatrixType& jac_mat, const DomainPointType& dom_point, const DataType* coeffs)
959 {
960 for(int idx = tg.thread_rank(); idx < 2*image_dim; idx += tg.num_threads())
961 {
962 __builtin_assume(idx >= 0);
963 const int i = idx/image_dim;
964 const int curr = idx%image_dim;
965 // a bit of branch free magic, TODO: we could even start with
966 jac_mat(i,curr) = coeffs[i*num_verts + curr+1] + dom_point[1-curr] * coeffs[i*num_verts + 3];
967 // printf("jac mat i %i, curr %i, coeff ent %i, dom ent %i, coeff ent %i\n", i, curr, int(i*num_verts+curr+1), int(1-curr), int(i*num_verts+3));
968 // printf("domp i %i, dp %f, coeff 1 %f, coeff 2 %f\n", idx, dom_point[1-curr], coeffs[i*num_verts +curr+1], coeffs[i*num_verts+3]);
969 }
970 }
971 #endif
972
986 {
987 for(int i(0); i < image_dim; ++i)
988 {
989 hess_ten(i,0,0) = hess_ten(i,1,1) = DataType(0);
990 hess_ten(i,0,1) = hess_ten(i,1,0) = coeffs[i][3];
991 }
992 }
993
1003 CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
1004 {
1005 // According to Varignon's theorem, the area/volume of a quadrilateral is
1006 // equal to twice the area of the dual parallelogram of the quadrilateral,
1007 // which is spanned by the four edge midpoints of the quadrilateral.
1008 // The Jacobian matrix of this transformation evaluated at the barycentre
1009 // of the reference element spans a parallelogram, which intersects with
1010 // our original quadrilateral in the edge midpoints and therefore (again
1011 // using Varignon's theorem) has the same area as the original quadrilateral.
1012 // Now the area of the "Jacobian parallelogram" is equal to four times
1013 // the determinant of its Jacobian determinant, which finally gives us a
1014 // formula for our quadrilateral area: 4*det(Jacobian(0,0)).
1015 // Note that this is not a lousy approximation, but a true identity :)
1016
1017 // compute jacobian matrix at barycentre
1019 for(int i(0); i < image_dim; ++i)
1020 {
1021 jac_mat(i,0) = coeffs[i][1];
1022 jac_mat(i,1) = coeffs[i][2];
1023 }
1024
1025 // return scaled volume
1026 return DataType(4) * jac_mat.vol();
1027 }
1028
1043 CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& ray, const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
1044 {
1047 DomainPointType ref_ray;
1048
1049 // compute jacobian matrix at barycentre
1050 for(int i(0); i < image_dim; ++i)
1051 {
1052 jac_mat(i,0) = coeffs[i][1];
1053 jac_mat(i,1) = coeffs[i][2];
1054 }
1055
1056 // invert jacobian matrix and multiply by ray vector
1057 jac_inv.set_inverse(jac_mat);
1058 ref_ray.set_mat_vec_mult(jac_inv, ray);
1059
1060 // return scaled inverse ray norm
1061 return DataType(2) / ref_ray.norm_euclid();
1062 }
1063 }; // EvalHelper<Hypercube<2>,...>
1064
1065 template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
1066 typename HessType_, typename HessInvType_, int img_dim>
1067 struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Hypercube<3>, img_dim>
1068 {
1070 typedef DataType_ DataType;
1072 typedef DomPointType_ DomainPointType;
1074 typedef ImgPointType_ ImagePointType;
1076 typedef JacMatType_ JacobianMatrixType;
1078 typedef JacMatInvType_ JacobianInverseType;
1080 typedef JacDetType_ JacobianDeterminantType;
1082 typedef HessType_ HessianTensorType;
1084 typedef HessInvType_ HessianInverseType;
1087
1088 static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
1089 static constexpr int image_dim = img_dim;
1090
1106 template<typename VertexSetType_, typename IndexSetType_, typename IT_>
1107 CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, img_dim, num_verts>& coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, IT_ cell_index)
1108 {
1109 typedef typename VertexSetType_::VertexType VertexType;
1110
1111 const VertexType& v0 = vertex_set[index_set(cell_index, 0)];
1112 const VertexType& v1 = vertex_set[index_set(cell_index, 1)];
1113 const VertexType& v2 = vertex_set[index_set(cell_index, 2)];
1114 const VertexType& v3 = vertex_set[index_set(cell_index, 3)];
1115 const VertexType& v4 = vertex_set[index_set(cell_index, 4)];
1116 const VertexType& v5 = vertex_set[index_set(cell_index, 5)];
1117 const VertexType& v6 = vertex_set[index_set(cell_index, 6)];
1118 const VertexType& v7 = vertex_set[index_set(cell_index, 7)];
1119
1120 // calculate transformation coefficients
1121 // j = _coeff[i][j] for all j = 0....7
1122 // v = 0 + 1*x + 2*y + 3*z + x*y*4 + x*z*5 + y*z*6 + x*y*z*7
1123 for(int i(0); i < image_dim; ++i)
1124 {
1125 coeffs[i][0] = DataType(0.125) * DataType( + v0[i] + v1[i] + v2[i] + v3[i] + v4[i] + v5[i] + v6[i] + v7[i]);
1126 coeffs[i][1] = DataType(0.125) * DataType( - v0[i] + v1[i] - v2[i] + v3[i] - v4[i] + v5[i] - v6[i] + v7[i]);
1127 coeffs[i][2] = DataType(0.125) * DataType( - v0[i] - v1[i] + v2[i] + v3[i] - v4[i] - v5[i] + v6[i] + v7[i]);
1128 coeffs[i][3] = DataType(0.125) * DataType( - v0[i] - v1[i] - v2[i] - v3[i] + v4[i] + v5[i] + v6[i] + v7[i]);
1129 coeffs[i][4] = DataType(0.125) * DataType( + v0[i] - v1[i] - v2[i] + v3[i] + v4[i] - v5[i] - v6[i] + v7[i]);
1130 coeffs[i][5] = DataType(0.125) * DataType( + v0[i] - v1[i] + v2[i] - v3[i] - v4[i] + v5[i] - v6[i] + v7[i]);
1131 coeffs[i][6] = DataType(0.125) * DataType( + v0[i] + v1[i] - v2[i] - v3[i] - v4[i] - v5[i] + v6[i] + v7[i]);
1132 coeffs[i][7] = DataType(0.125) * DataType( - v0[i] + v1[i] + v2[i] - v3[i] + v4[i] - v5[i] - v6[i] + v7[i]);
1133 }
1134
1135 }
1136
1137 #ifdef __CUDACC__
1138 template<typename ThreadGroup_, typename VertexSetType_, typename IndexSetType_>
1139 CUDA_DEVICE static void __forceinline__ _group_gather_vertex_set(const ThreadGroup_& tg, typename VertexSetType_::VertexType* __restrict__ vn, const VertexSetType_& vertex_set, const IndexSetType_& index_set, const Index cell_index)
1140 {
1141 // use block strided access pattern
1142 for(int i = tg.thread_rank(); i < num_verts; i += tg.num_threads())
1143 vn[i] = vertex_set[index_set(cell_index, i)];
1144 }
1145
1146 template<typename ThreadGroup_, typename VertexType_>
1147 CUDA_DEVICE static void __forceinline__ _group_set_coeffs(const ThreadGroup_& tg, DataType* __restrict__ coeffs, const VertexType_* __restrict__ vn)
1148 {
1149 // calculate transformation coefficients
1150 // j = _coeff[i][j] for all j = 0....7
1151 // v = 0 + 1*x + 2*y + 3*z + x*y*4 + x*z*5 + y*z*6 + x*y*z*7
1152 // there is simply no nice way to do this... still, it seems directly transmitting the coeffs could be more efficient...
1153 for(int i = tg.thread_rank(); i < image_dim; i += tg.num_threads())
1154 {
1155 coeffs[8*i+0] = DataType(0.125) * DataType( + vn[0][i] + vn[1][i] + vn[2][i] + vn[3][i] + vn[4][i] + vn[5][i] + vn[6][i] + vn[7][i]);
1156 coeffs[8*i+1] = DataType(0.125) * DataType( - vn[0][i] + vn[1][i] - vn[2][i] + vn[3][i] - vn[4][i] + vn[5][i] - vn[6][i] + vn[7][i]);
1157 coeffs[8*i+2] = DataType(0.125) * DataType( - vn[0][i] - vn[1][i] + vn[2][i] + vn[3][i] - vn[4][i] - vn[5][i] + vn[6][i] + vn[7][i]);
1158 coeffs[8*i+3] = DataType(0.125) * DataType( - vn[0][i] - vn[1][i] - vn[2][i] - vn[3][i] + vn[4][i] + vn[5][i] + vn[6][i] + vn[7][i]);
1159 coeffs[8*i+4] = DataType(0.125) * DataType( + vn[0][i] - vn[1][i] - vn[2][i] + vn[3][i] + vn[4][i] - vn[5][i] - vn[6][i] + vn[7][i]);
1160 coeffs[8*i+5] = DataType(0.125) * DataType( + vn[0][i] - vn[1][i] + vn[2][i] - vn[3][i] - vn[4][i] + vn[5][i] - vn[6][i] + vn[7][i]);
1161 coeffs[8*i+6] = DataType(0.125) * DataType( + vn[0][i] + vn[1][i] - vn[2][i] - vn[3][i] - vn[4][i] - vn[5][i] + vn[6][i] + vn[7][i]);
1162 coeffs[8*i+7] = DataType(0.125) * DataType( - vn[0][i] + vn[1][i] + vn[2][i] - vn[3][i] + vn[4][i] - vn[5][i] - vn[6][i] + vn[7][i]);
1163 }
1164 }
1185 template<typename ThreadGroup_, typename VertexSetType_, typename IndexSetType_, typename IT_>
1186 CUDA_DEVICE static void inline grouped_set_coefficients(const ThreadGroup_& tg, DataType* coeffs, const VertexSetType_& vertex_set, const IndexSetType_& index_set, const IT_ cell_index)
1187 {
1188 typedef typename VertexSetType_::VertexType VertexType;
1189 // get shared vertex set array
1190 __shared__ VertexType vn[8];
1191
1192 _group_gather_vertex_set(tg, vn, vertex_set, index_set, cell_index);
1193
1194 tg.sync();
1195
1196 _group_set_coeffs(tg, coeffs, vn);
1197
1198 tg.sync();
1199 }
1200 #endif
1201
1215 {
1216 for(int i(0); i < image_dim; ++i)
1217 {
1218 img_point[i] = coeffs[i][0]
1219 + dom_point[0] * (coeffs[i][1])
1220 + dom_point[1] * (coeffs[i][2] + dom_point[0]*coeffs[i][4])
1221 + dom_point[2] * (coeffs[i][3] + dom_point[0]*coeffs[i][5]
1222 + dom_point[1] * (coeffs[i][6] + dom_point[0]*coeffs[i][7]));
1223 }
1224 }
1225
1239 {
1240 for(int i(0); i < image_dim; ++i)
1241 {
1242 jac_mat(i,0) = coeffs[i][1] + dom_point[1] * coeffs[i][4] + dom_point[2] * (coeffs[i][5] + dom_point[1] * coeffs[i][7]);
1243 jac_mat(i,1) = coeffs[i][2] + dom_point[0] * coeffs[i][4] + dom_point[2] * (coeffs[i][6] + dom_point[0] * coeffs[i][7]);
1244 jac_mat(i,2) = coeffs[i][3] + dom_point[0] * coeffs[i][5] + dom_point[1] * (coeffs[i][6] + dom_point[0] * coeffs[i][7]);
1245 }
1246 }
1247
1248 #ifdef __CUDACC__
1268 template<typename ThreadGroup_>
1269 CUDA_DEVICE static inline void grouped_calc_jac_mat(const ThreadGroup_& tg, JacobianMatrixType& jac_mat, const DomainPointType& dom_point, const DataType* coeffs)
1270 {
1271 for(int idx = tg.thread_rank(); idx < 3*image_dim; idx += tg.num_threads())
1272 {
1273 __builtin_assume(idx >= 0);
1274 const int i = idx/image_dim;
1275 const int curr = idx%image_dim;
1276 // a bit of branch free magic, TODO: we could even start with
1277 jac_mat(i,curr) = coeffs[i*num_verts + curr+1] + dom_point[1-(curr+1)/2] * coeffs[i* num_verts + 4+curr/2] + dom_point[2-curr/2] * (coeffs[i*num_verts + 5+(curr+1)/2] + dom_point[1-(curr+1)/2] * coeffs[i*num_verts + 7]);
1278 }
1279 }
1280 #endif
1281
1295 {
1296 for(int i(0); i < image_dim; ++i)
1297 {
1298 hess_ten(i,0,0) = hess_ten(i,1,1) = hess_ten(i,2,2) = DataType(0);
1299 hess_ten(i,0,1) = hess_ten(i,1,0) = coeffs[i][4] + coeffs[i][7] * dom_point[2];
1300 hess_ten(i,0,2) = hess_ten(i,2,0) = coeffs[i][5] + coeffs[i][7] * dom_point[1];
1301 hess_ten(i,1,2) = hess_ten(i,2,1) = coeffs[i][6] + coeffs[i][7] * dom_point[0];
1302 }
1303 }
1304
1314 CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
1315 {
1316 // In contrast to 2D, it is not sufficient to evaluate the Jacobian determinant
1317 // in the barycentre of the cell to compute the cell's volume, as this will give
1318 // very inaccurate results for non-parallelepiped cells. Instead, we have to use
1319 // the 2x2x2 Gauss-Legendre cubature rule to integrate the volume of the cell,
1320 // which is hard-coded in the code below.
1321
1322 // compute 1D Gauss-Legendre root
1323 const DataType cx = DataType(FEAT_F128C(0.57735026918962576450914878050195745564760175127));
1324
1326 DomainPointType cub_pt;
1327 DataType vol = DataType(0);
1328
1329 // loop over all 8 cubature points
1330 for(int i(0); i < 8; ++i)
1331 {
1332 // set cubature point coords by magic bitshifts
1333 for(int j(0); j < 3; ++j)
1334 cub_pt[j] = DataType((((i >> j) & 1) << 1) - 1) * cx;
1335
1336 // compute jacobian matrix and add its volume
1337 calc_jac_mat(jac_mat, cub_pt, coeffs);
1338 vol += jac_mat.vol();
1339 }
1340
1341 return vol;
1342 }
1343
1358 CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& ray, const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
1359 {
1362 DomainPointType ref_ray;
1363
1364 // compute jacobian matrix at barycentre
1365 for(int i(0); i < image_dim; ++i)
1366 {
1367 jac_mat(i,0) = coeffs[i][1];
1368 jac_mat(i,1) = coeffs[i][2];
1369 jac_mat(i,2) = coeffs[i][3];
1370 }
1371
1372 // invert jacobian matrix and multiply by ray vector
1373 jac_inv.set_inverse(jac_mat);
1374 ref_ray.set_mat_vec_mult(jac_inv, ray);
1375
1376 // return scaled inverse ray norm
1377 return DataType(2) / ref_ray.norm_euclid();
1378 }
1379 }; // EvalHelper<Hypercube<3>,...>
1380
1381 // template<typename DataType_, typename DomPointType_, typename ImgPointType_, typename JacMatType_, typename JacMatInvType_, typename JacDetType_,
1382 // typename HessType_, typename HessInvType_, int img_dim>
1383 // struct EvalHelper<DataType_, DomPointType_, ImgPointType_, JacMatType_, JacMatInvType_, JacDetType_, HessType_, HessInvType_, Shape::Vertex, img_dim>
1384 // {
1385 // /// evaluation data type
1386 // typedef DataType_ DataType;
1387 // /// domain point type
1388 // typedef DomPointType_ DomainPointType;
1389 // /// image point type
1390 // typedef ImgPointType_ ImagePointType;
1391 // /// jacobian matrix type
1392 // typedef JacMatType_ JacobianMatrixType;
1393 // /// jacobian inverse matrix type
1394 // typedef JacMatInvType_ JacobianInverseType;
1395 // /// jacobian determinant type
1396 // typedef JacDetType_ JacobianDeterminantType;
1397 // /// hessian tensor type
1398 // typedef HessType_ HessianTensorType;
1399 // /// hessian inverse tensor type
1400 // typedef HessInvType_ HessianInverseType;
1401 // /// the shape type
1402 // typedef Shape::Vertex ShapeType;
1403
1404 // static constexpr int num_verts = Shape::FaceTraits<ShapeType, 0>::count;
1405 // static constexpr int image_dim = img_dim;
1406
1407 // template<typename VertexSetType_, typename IndexTupleType_>
1408 // CUDA_HOST_DEVICE static void inline set_coefficients(Tiny::Matrix<DataType, image_dim, num_verts>& coeffs, const IndexTupleType_& DOXY(index_tuple), const VertexSetType_& vertex_set)
1409 // {
1410 // const auto& vtx = vertex_set;
1411
1412 // for(int i(0); i < image_dim; ++i)
1413 // {
1414 // coeffs[i][0] = DataType(vtx[i]);
1415 // }
1416
1417 // }
1418
1419 // CUDA_HOST_DEVICE static inline void map_point(ImagePointType& img_point, const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& coeffs)
1420 // {
1421 // for(int i(0); i < image_dim; ++i)
1422 // {
1423 // img_point[i] = coeffs[i][0];
1424 // }
1425 // }
1426
1427 // CUDA_HOST_DEVICE static inline void calc_jac_mat(JacobianMatrixType& DOXY(jac_mat), const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
1428 // {
1429 // }
1430
1431 // CUDA_HOST_DEVICE static inline void calc_hess_ten(HessianTensorType& DOXY(hess_ten), const DomainPointType& DOXY(dom_point), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
1432 // {
1433 // }
1434
1435 // CUDA_HOST_DEVICE static inline DataType volume(const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
1436 // {
1437 // }
1438
1439 // CUDA_HOST_DEVICE static inline DataType width_directed(const ImagePointType& DOXY(ray), const Tiny::Matrix<DataType, image_dim, num_verts>& DOXY(coeffs))
1440 // {
1441 // }
1442 // };
1443 }
1444 }
1445}
FEAT Kernel base header.
Tiny Matrix class template.
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
T_ sqr(T_ x)
Returns the square of a value.
Definition: math.hpp:95
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
@ img_point
specifies whether the trafo should supply image point coordinates
@ dom_point
specifies whether the trafo should supply domain point coordinates
@ hess_ten
specifies whether the trafo should supply hessian tensors
@ jac_inv
specifies whether the trafo should supply inverse jacobian matrices
@ jac_mat
specifies whether the trafo should supply jacobian matrices
Face traits tag struct template.
Definition: shape.hpp:106
Hypercube shape tag struct template.
Definition: shape.hpp:64
Simplex shape tag struct template.
Definition: shape.hpp:44
static CUDA_HOST_DEVICE void set_coefficients(Tiny::Matrix< DataType, image_dim, num_verts > &coeffs, const VertexSetType_ &vertex_set, const IndexSetType_ &index_set, IT_ cell_index)
Sets the coefficient vector based on the underlying standard transformation.
Definition: details.hpp:804
static CUDA_HOST_DEVICE void map_point(ImagePointType &img_point, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Maps a point from the reference cell to the selected cell.
Definition: details.hpp:907
static CUDA_HOST_DEVICE void calc_jac_mat(JacobianMatrixType &jac_mat, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Calculates the jacobian matrix for a given point.
Definition: details.hpp:928
static CUDA_HOST_DEVICE void calc_hess_ten(HessianTensorType &hess_ten, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes the hessian tensor for a given domain point.
Definition: details.hpp:985
static CUDA_HOST_DEVICE DataType volume(const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the volume of the current cell.
Definition: details.hpp:1003
static CUDA_HOST_DEVICE DataType width_directed(const ImagePointType &ray, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the directed mesh width.
Definition: details.hpp:1043
static CUDA_HOST_DEVICE void calc_hess_ten(HessianTensorType &hess_ten, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes the hessian tensor for a given domain point.
Definition: details.hpp:161
static CUDA_HOST_DEVICE DataType width_directed(const ImagePointType &ray, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the directed mesh width.
Definition: details.hpp:203
static CUDA_HOST_DEVICE void set_coefficients(Tiny::Matrix< DataType, image_dim, num_verts > &coeffs, const VertexSetType_ &vertex_set, const IndexSetType_ &index_set, IT_ cell_index)
Sets the coefficient vector based on the underlying standard transformation.
Definition: details.hpp:93
static CUDA_HOST_DEVICE void map_point(ImagePointType &img_point, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Maps a point from the reference cell to the selected cell.
Definition: details.hpp:121
static CUDA_HOST_DEVICE DataType volume(const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the volume of the current cell.
Definition: details.hpp:175
static CUDA_HOST_DEVICE void calc_jac_mat(JacobianMatrixType &jac_mat, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Calculates the jacobian matrix for a given point.
Definition: details.hpp:141
static CUDA_HOST_DEVICE void set_coefficients(Tiny::Matrix< DataType, image_dim, num_verts > &coeffs, const VertexSetType_ &vertex_set, const IndexSetType_ &index_set, IT_ cell_index)
Sets the coefficient vector based on the underlying standard transformation.
Definition: details.hpp:253
static CUDA_HOST_DEVICE void calc_hess_ten(HessianTensorType &hess_ten, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes the hessian tensor for a given domain point.
Definition: details.hpp:324
static CUDA_HOST_DEVICE DataType volume(const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the volume of the current cell.
Definition: details.hpp:338
static CUDA_HOST_DEVICE void map_point(ImagePointType &img_point, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Maps a point from the reference cell to the selected cell.
Definition: details.hpp:283
static CUDA_HOST_DEVICE DataType width_directed(const ImagePointType &ray, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the directed mesh width.
Definition: details.hpp:363
static CUDA_HOST_DEVICE void calc_jac_mat(JacobianMatrixType &jac_mat, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Calculates the jacobian matrix for a given point.
Definition: details.hpp:303
static CUDA_HOST_DEVICE void set_coefficients(Tiny::Matrix< DataType, image_dim, num_verts > &coeffs, const VertexSetType_ &vertex_set, const IndexSetType_ &index_set, IT_ cell_index)
Sets the coefficient vector based on the underlying standard transformation.
Definition: details.hpp:447
static CUDA_HOST_DEVICE void map_point(ImagePointType &img_point, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Maps a point from the reference cell to the selected cell.
Definition: details.hpp:479
static CUDA_HOST_DEVICE void calc_hess_ten(HessianTensorType &hess_ten, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes the hessian tensor for a given domain point.
Definition: details.hpp:523
static CUDA_HOST_DEVICE DataType width_directed(const ImagePointType &ray, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the directed mesh width.
Definition: details.hpp:563
static CUDA_HOST_DEVICE DataType volume(const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the volume of the current cell.
Definition: details.hpp:537
static CUDA_HOST_DEVICE void calc_jac_mat(JacobianMatrixType &jac_mat, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Calculates the jacobian matrix for a given point.
Definition: details.hpp:501
static CUDA_HOST_DEVICE void calc_hess_ten(HessianTensorType &hess_ten, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes the hessian tensor for a given domain point.
Definition: details.hpp:1294
static CUDA_HOST_DEVICE void set_coefficients(Tiny::Matrix< DataType, img_dim, num_verts > &coeffs, const VertexSetType_ &vertex_set, const IndexSetType_ &index_set, IT_ cell_index)
Sets the coefficient vector based on the underlying standard transformation.
Definition: details.hpp:1107
static CUDA_HOST_DEVICE DataType volume(const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the volume of the current cell.
Definition: details.hpp:1314
static CUDA_HOST_DEVICE void map_point(ImagePointType &img_point, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Maps a point from the reference cell to the selected cell.
Definition: details.hpp:1214
static CUDA_HOST_DEVICE void calc_jac_mat(JacobianMatrixType &jac_mat, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Calculates the jacobian matrix for a given point.
Definition: details.hpp:1238
static CUDA_HOST_DEVICE DataType width_directed(const ImagePointType &ray, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the directed mesh width.
Definition: details.hpp:1358
static CUDA_HOST_DEVICE void map_point(ImagePointType &img_point, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Maps a point from the reference cell to the selected cell.
Definition: details.hpp:673
static CUDA_HOST_DEVICE void set_coefficients(Tiny::Matrix< DataType, image_dim, num_verts > &coeffs, const VertexSetType_ &vertex_set, const IndexSetType_ &index_set, IT_ cell_index)
Sets the coefficient vector based on the underlying standard transformation.
Definition: details.hpp:645
static CUDA_HOST_DEVICE DataType width_directed(const ImagePointType &ray, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the directed mesh width.
Definition: details.hpp:755
static CUDA_HOST_DEVICE DataType volume(const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes and returns the volume of the current cell.
Definition: details.hpp:727
static CUDA_HOST_DEVICE void calc_jac_mat(JacobianMatrixType &jac_mat, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Calculates the jacobian matrix for a given point.
Definition: details.hpp:693
static CUDA_HOST_DEVICE void calc_hess_ten(HessianTensorType &hess_ten, const DomainPointType &dom_point, const Tiny::Matrix< DataType, image_dim, num_verts > &coeffs)
Computes the hessian tensor for a given domain point.
Definition: details.hpp:713
Evalautator helper class for standard trafo.
Definition: details.hpp:48