FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
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
9#include <kernel/assembly/base.hpp>
10#include <kernel/lafem/dense_vector.hpp>
11#include <kernel/lafem/dense_vector_blocked.hpp>
12
13namespace FEAT
14{
15 namespace Assembly
16 {
18 namespace Intern
19 {
20 template<
21 typename Vector_,
22 typename Function_,
23 typename Space_,
24 int shape_dim_,
25 int max_dofs_ = Space_::template NodeFunctional<shape_dim_, typename Vector_::DataType>::Type::max_assigned_dofs>
26 struct InterpolatorCore
27 {
28 public:
29 static void project(Vector_& vector, const Function_& function, const Space_& space)
30 {
31 typedef typename Vector_::DataType DataType;
32
33 // create a node-functional object
34 typedef typename Space_::template NodeFunctional<shape_dim_, DataType>::Type NodeFunc;
35
36 typedef typename NodeFunc::template Value<Function_>::Type ValueType;
37
38 const Index num_entities = space.get_mesh().get_num_entities(shape_dim_);
39
40 FEAT_PRAGMA_OMP(parallel)
41 {
42 // create node functional
43 NodeFunc node_func(space);
44
45 // create node data; avoid zero-length vectors
46 Tiny::Vector<ValueType, max_dofs_> node_data;
47
48 // define dof assignment
49 typedef typename Space_::template DofAssignment<shape_dim_, DataType>::Type DofAssignType;
50 DofAssignType dof_assign(space);
51
52 // get the vector data array
53 auto* vals = vector.elements();
54 XASSERT(vals != nullptr);
55
56 // loop over all entities
57 FEAT_PRAGMA_OMP(for)
58 for(Index i = 0; i < num_entities; ++i)
59 {
60 // evaluate the node functional
61 node_func.prepare(i);
62 node_func(node_data, function);
63 node_func.finish();
64
65 // prepare dof-assignment
66 dof_assign.prepare(i);
67
68 // loop over all assigned DOFs
69 const int num_dofs = dof_assign.get_num_assigned_dofs();
70 for(int j(0); j < num_dofs; ++j)
71 {
72 vals[dof_assign.get_index(j)] += node_data[j];
73 }
74
75 // finish
76 dof_assign.finish();
77 }
78 }
79 } // omp parallel
80 };
81
82 template<typename Vector_, typename Function_, typename Space_, int shape_dim_>
83 struct InterpolatorCore<Vector_, Function_, Space_, shape_dim_, 0>
84 {
85 static void project(Vector_&, const Function_&, const Space_&)
86 {
87 // do nothing
88 }
89 };
90
91 template<typename Space_, int shape_dim_ = Space_::shape_dim>
92 class InterpolatorWrapper
93 {
94 public:
95 template<typename Vector_, typename Function_>
96 static void project(Vector_& vector, const Function_& function, const Space_& space)
97 {
98 // recurse down
99 InterpolatorWrapper<Space_, shape_dim_ - 1>::project(vector, function, space);
100
101 // call interpolator core
102 InterpolatorCore<Vector_, Function_, Space_, shape_dim_>::project(vector, function, space);
103 }
104 };
105
106 template<typename Space_>
107 class InterpolatorWrapper<Space_, 0>
108 {
109 public:
110 template<typename Vector_, typename Function_>
111 static void project(Vector_& vector, const Function_& function, const Space_& space)
112 {
113 // call interpolator core
114 InterpolatorCore<Vector_, Function_, Space_, 0>::project(vector, function, space);
115 }
116 };
117 } // namespace Intern
119
129 {
130 public:
145 template<
146 typename DT_,
147 typename IT_,
148 typename Function_,
149 typename Space_>
150 static void project(
152 const Function_& function,
153 const Space_& space)
154 {
155 typedef typename Space_::TrafoType TrafoType;
156 typedef typename Function_::ImageType ImageType;
157
158 // as a very first step, ensure that the function has the right dimensions
159 static_assert(Function_::domain_dim == TrafoType::world_dim, "invalid function domain dimension");
160 static_assert(ImageType::is_scalar, "only scalar functions can be interpolated to scalar vectors");
161
162 // project function
163 vector = LAFEM::DenseVector<DT_, IT_>(space.get_num_dofs(), DT_(0));
164 Intern::InterpolatorWrapper<Space_>::project(vector, function, space);
165 }
166
181 template<
182 typename DT_,
183 typename IT_,
184 int block_size_,
185 typename Function_,
186 typename Space_>
187 static void project(
189 const Function_& function,
190 const Space_& space)
191 {
192 typedef typename Space_::TrafoType TrafoType;
193 typedef typename Function_::ImageType ImageType;
194
195 // as a very first step, ensure that the function has the right dimensions
196 static_assert(Function_::domain_dim == TrafoType::world_dim, "invalid function domain dimension");
197 static_assert(ImageType::is_vector, "only vector fields can be interpolated to blocked vectors");
198 static_assert(ImageType::image_dim == block_size_, "invalid vector field size");
199
200 // project function
201 vector = LAFEM::DenseVectorBlocked<DT_, IT_, block_size_>(space.get_num_dofs(), DT_(0));
202 Intern::InterpolatorWrapper<Space_>::project(vector, function, space);
203 }
204 }; // class Interpolator
205 } // namespace Assembly
206} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
Interpolator class template.
static void project(LAFEM::DenseVector< DT_, IT_ > &vector, const Function_ &function, const Space_ &space)
Interpolates a scalar function.
static void project(LAFEM::DenseVectorBlocked< DT_, IT_, block_size_ > &vector, const Function_ &function, const Space_ &space)
Interpolates a vector field.
Blocked Dense data vector class template.
Dense data vector class template.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.