FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
inverse_mapping.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
8#include <kernel/util/tiny_algebra.hpp>
9
10namespace FEAT
11{
12 namespace Trafo
13 {
14 namespace Standard
15 {
67 template<typename DT_, int helper_dim, int world_dim, int sc_, int sp_, int smx_, int snx_,
68 typename std::enable_if<helper_dim == world_dim+1, bool>::type = true>
73 {
74 // A will contain the transformation matrix
76 for(int i(0); i < world_dim; ++i)
77 {
78 for(int j(0); j < world_dim; ++j)
79 {
80 A(i,j) = x(j+1,i) - x(0,i);
81 }
82 }
83
84 // This will be the inverse of the transformation matrix
86 Ainv.set_inverse(A);
87
88 // This is the solution of A u = point - x[0]
89 coeffs = Ainv*(point - x[0]);
90 }
91
140 template<typename DT_, int world_dim, int sc_, int sp_, int smx_, int snx_>
145 {
146 static_assert( (world_dim == 2 || world_dim == 3),
147 "world dim has to be 2 or 3 for complementary barycentric coordinates");
148
149 auto tmp = x[1]-x[0];
150 DT_ sp(Tiny::dot(point - x[0],tmp));
151 DT_ nsqr(Math::sqr(tmp.norm_euclid()));
152 // This is omega
153 coeffs[0] = sp/nsqr;
154 tmp = point - (x[0] + coeffs[0]*(x[1]-x[0]));
155 // This is the distance of point to the straight line defined by x[0], x[1]
156 coeffs[1] = tmp.norm_euclid();
157 }
158
204 template<typename DT_, int sc_, int sp_, int smx_, int snx_>
207 const Tiny::Vector<DT_, 3, sp_>& point,
209 {
210 static constexpr int world_dim = 3;
211 static constexpr int shape_dim = world_dim-1;
212
213 // A will contain the transformation matrix
215 // Fill the all rows in the first shape_dim = world_dim-1 columns
216 for(int i(0); i < world_dim; ++i)
217 {
218 for(int j(0); j < shape_dim; ++j)
219 A(i,j) = x(j+1,i) - x(0,i);
220 }
221
222 // The last column is the additional direction for our augmented simplex and it is orthogonal to the rest
224 Tiny::orthogonal_3x2(ortho, A);
225
226 // In 3d, the 2-norm of ortho is the 2d volume of the parallelogram defined by A[0], A[1]. That makes this
227 // axis badly scaled if the parallelogram is either very small or very large. So we rescale ortho to unity
228 // so the resulting coefficient is just the distance
229 ortho.normalize();
230
231 // Set the last column in A
232 for(int i(0); i < world_dim; ++i)
233 A(i,world_dim-1) = ortho(i);
234
235 // This will be the inverse of the transformation matrix
237 Ainv.set_inverse(A);
238
239 // This is the solution of A u = point - x[0]
240 coeffs = Ainv*(point - x[0]);
241 }
242
243 } // namespace Standard
244 } // namespace Trafo
245} // namespace FEAT
FEAT Kernel base header.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_inverse(const Matrix< T_, m_, n_, sma_, sna_ > &a)
Sets this matrix to the inverse of another matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE Vector & normalize()
Normalizes this vector.
CUDA_HOST_DEVICE DataType norm_euclid() const
Computes the euclid norm of this vector.
T_ sqr(T_ x)
Returns the square of a value.
Definition: math.hpp:95
CUDA_HOST_DEVICE T_ dot(const T_ &a, const T_ &b)
Computes the dot-product of two scalars.
CUDA_HOST_DEVICE void orthogonal_3x2(Vector< T_, mx_, smx_ > &nu, const Matrix< T_, ma_, na_, sm_, sn_ > &tau)
Computes the positively oriented orthogonal vector to the columns of a 3x2 matrix.
void inverse_mapping(Tiny::Vector< DT_, world_dim, sc_ > &coeffs, const Tiny::Vector< DT_, world_dim, sp_ > &point, const Tiny::Matrix< DT_, helper_dim, world_dim, smx_, snx_ > &x)
Computes the inverse coordinate mapping wrt. a full-dimensional Simplex.
FEAT namespace.
Definition: adjactor.hpp:12