FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
fe_interpolator.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// includes, FEAT
10#include <kernel/lafem/dense_vector.hpp>
11#include <kernel/lafem/dense_vector_blocked.hpp>
12#include <kernel/space/lagrange1/element.hpp>
13#include <kernel/space/lagrange2/element.hpp>
14#include <kernel/util/math.hpp>
15
16namespace FEAT
17{
18 namespace Assembly
19 {
20
37 template<typename ToSpace_, typename FromSpace_>
39 {
40 };
41
57 template<typename Trafo_, int shape_dim_ = Trafo_::MeshType::shape_dim>
59 {
64
84 template<typename Vector_>
85 static void recurse(Vector_& to_coeffs, const Vector_& from_coeffs, const ToSpace& to_space)
86 {
87 typedef typename Vector_::DataType DataType;
88
89 const auto& mesh = to_space.get_trafo().get_mesh();
90
91 // We use this to identify the vertex DoF at our shape
92 const auto& from_vertex_at_shape_idx = mesh.template get_index_set<shape_dim_, 0>();
93
94 // This is for mapping to the correct Lagrange2 DoF
95 typename ToSpace::template DofAssignment<shape_dim_, DataType>::Type to_dof_assignment(to_space);
96
97 for(Index k(0); k < mesh.get_num_entities(shape_dim_); ++k)
98 {
99 to_dof_assignment.prepare(k);
100
101 // There is only one Lagrange2 DoF at each entity, but this is easier to understand for future reference
102 for(int j(0); j < to_dof_assignment.get_num_assigned_dofs(); ++j)
103 {
104
105 typename Vector_::ValueType tmp(0);
106
107 for(int i(0); i < from_vertex_at_shape_idx.get_num_indices(); ++i)
108 {
109 tmp += from_coeffs(from_vertex_at_shape_idx(k,i));
110 }
111
112 // Linear interpolation
113 tmp *= ( DataType(1)/DataType(from_vertex_at_shape_idx.get_num_indices()) );
114
115 // Emplacement operator
116 to_coeffs(to_dof_assignment.get_index(j), tmp);
117 }
118 }
119
120 // recurse down
121 Lagrange1To2DofAtEntity<Trafo_, shape_dim_-1>::recurse( to_coeffs, from_coeffs, to_space);
122 }
123 };
124
132 template<typename Trafo_>
133 struct Lagrange1To2DofAtEntity<Trafo_, 0>
134 {
137
157 template<typename Vector_>
158 static void recurse(Vector_& to_coeffs, const Vector_& from_coeffs, const ToSpace& to_space)
159 {
160
161 const auto& mesh = to_space.get_trafo().get_mesh();
162
163 for(Index i(0); i < mesh.get_num_entities(0); ++i)
164 {
165 to_coeffs(i, from_coeffs(i));
166 }
167
168 }
169 };
170
179 template<typename Trafo_>
180 struct FEInterpolator<Space::Lagrange2::Element<Trafo_>, Space::Lagrange1::Element<Trafo_>>
181 {
183 typedef Trafo_ TrafoType;
188
211 template<typename DT_, typename IT_>
213 const LAFEM::DenseVector<DT_, IT_>& from_coeffs,
214 const ToSpace& to_space,
215 const FromSpace& DOXY(from_space))
216 {
217 Lagrange1To2DofAtEntity<TrafoType>::recurse(to_coeffs, from_coeffs, to_space);
218 }
219
242 template<typename DT_, typename IT_, int blocksize_>
245 const ToSpace& to_space,
246 const FromSpace& DOXY(from_space))
247 {
248 Lagrange1To2DofAtEntity<TrafoType>::recurse(to_coeffs, from_coeffs, to_space);
249 }
250 }; //FEInterpolator Lagrange1 to Lagrange2
251
260 template<typename Trafo_>
261 struct FEInterpolator<Space::Lagrange1::Element<Trafo_>, Space::Lagrange2::Element<Trafo_>>
262 {
264 typedef Trafo_ TrafoType;
269
292 template<typename DT_, typename IT_>
294 const LAFEM::DenseVector<DT_, IT_>& from_coeffs,
295 const ToSpace& DOXY(to_space),
296 const FromSpace& DOXY(from_space))
297 {
298 //sanity check for the vector sizes
299 XASSERTM(to_coeffs.size() < from_coeffs.size(), "Coefficient vectors do not match!\n To_coeffs size is ");
300 //due to the two level ordering of Lagrange1 and Lagrange2 elements it is always sufficient to just truncate our vector
301 for(Index i(0); i < to_coeffs.size(); ++i)
302 {
303 to_coeffs(i, from_coeffs(i));
304 }
305 //And we are done
306 }
307
330 template<typename DT_, typename IT_, int blocksize_>
333 const ToSpace& DOXY(to_space),
334 const FromSpace& DOXY(from_space))
335 {
336 //sanity check for the vector sizes
337 XASSERTM(to_coeffs.size() < from_coeffs.size(), "Coefficient vectors do not match!\n To_coeffs size is ");
338 //due to the two level ordering of Lagrange1 and Lagrange2 elements it is always sufficient to only truncate our vector
339 for(Index i(0); i < to_coeffs.size(); ++i)
340 {
341 to_coeffs(i, from_coeffs(i));
342 }
343 //And we are done
344 }
345
346 }; //FEInterpolator Lagrange2 to Lagrange1
347
356 template<typename Space_>
357 struct FEInterpolator<Space_, Space_>
358 {
359 typedef Space_ ToSpace;
360
361 typedef Space_ FromSpace;
362
387 template<typename Vector_>
388 static void interpolate(Vector_& to_coeffs,
389 const Vector_& from_coeffs,
390 const ToSpace& DOXY(to_space),
391 const FromSpace& DOXY(from_space))
392 {
393 to_coeffs.copy(from_coeffs, true);
394 }
395
396 }; //FEInterpolator same space
397
398 } // namespace Assembly
399} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Index size() const
Returns the containers size.
Definition: container.hpp:1136
Blocked Dense data vector class template.
Index size() const
The number of elements.
Dense data vector class template.
TrafoType & get_trafo()
Returns a reference to the trafo.
Standard Lagrange-1 Finite-Element space class template.
Definition: element.hpp:39
Standard Lagrange-2 Finite-Element space class template.
Definition: element.hpp:39
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
static void interpolate(LAFEM::DenseVectorBlocked< DT_, IT_, blocksize_ > &to_coeffs, const LAFEM::DenseVectorBlocked< DT_, IT_, blocksize_ > &from_coeffs, const ToSpace &to_space, const FromSpace &from_space)
Interpolates a vector Lagrange1 to Lagrange2 FE function.
static void interpolate(LAFEM::DenseVector< DT_, IT_ > &to_coeffs, const LAFEM::DenseVector< DT_, IT_ > &from_coeffs, const ToSpace &to_space, const FromSpace &from_space)
Interpolates a scalar Lagrange1 to Lagrange2 FE function.
static void interpolate(LAFEM::DenseVectorBlocked< DT_, IT_, blocksize_ > &to_coeffs, const LAFEM::DenseVectorBlocked< DT_, IT_, blocksize_ > &from_coeffs, const ToSpace &to_space, const FromSpace &from_space)
Interpolates a vector valued Lagrange1 to Lagrange2 FE function.
static void interpolate(LAFEM::DenseVector< DT_, IT_ > &to_coeffs, const LAFEM::DenseVector< DT_, IT_ > &from_coeffs, const ToSpace &to_space, const FromSpace &from_space)
Interpolates a scalar Lagrange1 to Lagrange2 FE function.
static void interpolate(Vector_ &to_coeffs, const Vector_ &from_coeffs, const ToSpace &to_space, const FromSpace &from_space)
Interpolates a scalar/vector FE function on the same space by just copying the vector.
Interpolation operator between two finite element spaces.
static void recurse(Vector_ &to_coeffs, const Vector_ &from_coeffs, const ToSpace &to_space)
Evaluates the node functionals for shape dimension 0.
Helper class that recurses through shape dimensions and evaluates Lagrange2 DoF based on Lagrange1 Do...
static void recurse(Vector_ &to_coeffs, const Vector_ &from_coeffs, const ToSpace &to_space)
Evaluates the node functionals from shape_dim_ on down to shape dimension 0.
Space::Lagrange2::Element< Trafo_ > ToSpace
We map to Lagrange2.
Space::Lagrange1::Element< Trafo_ > FromSpace
We map from Lagrange1.