FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
rew_projector.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/analytic/function.hpp>
10#include <kernel/assembly/asm_traits.hpp>
11#include <kernel/lafem/dense_vector.hpp>
12#include <kernel/util/math.hpp>
13
14namespace FEAT
15{
16 namespace Assembly
17 {
28 {
29 public:
33 enum class WeightType
34 {
36 arithmetic = 0,
38 volume
39 };
40
62 template<
63 typename DT_,
64 typename IT_,
65 typename Function_,
66 typename Space_,
67 typename CubatureFactory_>
68 static void project(
70 const Function_& function,
71 const Space_& space,
72 const CubatureFactory_& cubature_factory,
73 WeightType weight_type = WeightType::volume)
74 {
75 typedef LAFEM::DenseVector<DT_, IT_> VectorType;
76 typedef Function_ FunctionType;
77 typedef Space_ SpaceType;
78 typedef typename SpaceType::TrafoType TrafoType;
79
80 static_assert(Function_::can_value, "analytic function can't compute function values");
81
82 // define assembly traits
84 typedef typename AsmTraits::DataType DataType;
85
86 // define the cubature rule
87 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
88
89 // fetch the trafo and the mesh
90 const TrafoType& trafo(space.get_trafo());
91
92 // create a trafo evaluator
93 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
94
95 // create a space evaluator and evaluation data
96 typename AsmTraits::SpaceEvaluator space_eval(space);
97
98 // create a dof-mapping
99 typename AsmTraits::DofMapping dof_mapping(space);
100
101 // define our analytic evaluation traits
102 typedef Analytic::EvalTraits<DataType, Function_> AnalyticEvalTraits;
103
104 // create a function evaluator
105 typename FunctionType::template Evaluator<AnalyticEvalTraits> func_eval(function);
106
107 // create trafo evaluation data
108 typename AsmTraits::TrafoEvalData trafo_data;
109
110 // create space evaluation data
111 typename AsmTraits::SpaceEvalData space_data;
112
113 // allocate fine-mesh mass matrix
114 typename AsmTraits::template TLocalMatrix<DT_> mass;
115
116 // pivot array for factorization
117 int pivot[mass.n];
118
119 // create local vector data
120 typename AsmTraits::template TLocalVector<DT_> lvad, lxad;
121
122 // create local weight data
123 typename AsmTraits::template TLocalVector<DT_> lwad;
124
125 // fetch the dof count
126 const Index num_dofs(space.get_num_dofs());
127
128 // create a clear output vector
129 vector = VectorType(num_dofs, DataType(0));
130
131 // allocate weight vector
132 VectorType weight(num_dofs, DataType(0));
133
134 // create vector scatter-axpy
135 typename VectorType::ScatterAxpy scatter_axpy(vector);
136
137 // create weight scatter-axpy
138 typename VectorType::ScatterAxpy weight_scatter_axpy(weight);
139
140 // format local weight vector
141 if(weight_type == WeightType::arithmetic)
142 lwad.format(DataType(1));
143
144 // loop over all cells of the mesh
145 for(Index cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
146 {
147 // prepare trafo evaluator
148 trafo_eval.prepare(cell);
149
150 // prepare space evaluator
151 space_eval.prepare(trafo_eval);
152
153 // fetch number of local dofs
154 int num_loc_dofs(space_eval.get_num_local_dofs());
155
156 // format local system
157 lvad.format();
158 mass.format();
159
160 // cell volume
161 DataType volume(DataType(0));
162
163 // loop over all cubature points and integrate
164 for(int k(0); k < cubature_rule.get_num_points(); ++k)
165 {
166 // compute trafo data
167 trafo_eval(trafo_data, cubature_rule.get_point(k));
168
169 // compute basis function data
170 space_eval(space_data, trafo_data);
171
172 // compute function value
173 DataType fv = func_eval.value(trafo_data.img_point);
174
175 // pre-compute integration weight
176 DataType omega(trafo_data.jac_det * cubature_rule.get_weight(k));
177
178 // update volume
179 volume += omega;
180
181 // test function loop
182 for(int i(0); i < num_loc_dofs; ++i)
183 {
184 // assemble RHS entry
185 lvad(i) += omega * fv * space_data.phi[i].value;
186
187 // trial function loop
188 for(int j(0); j < num_loc_dofs; ++j)
189 {
190 mass(i,j) += omega * space_data.phi[i].value * space_data.phi[j].value;
191 }
192 }
193 }
194
195 // finish evaluators
196 space_eval.finish();
197 trafo_eval.finish();
198
199 // try to factorize the local mass matrix
200 Math::invert_matrix(num_loc_dofs, mass.sn, &mass.v[0][0], pivot);
201
202 // solve M*x=f
203 lxad.set_mat_vec_mult(mass, lvad);
204
205 // choose weight
206 if(weight_type == WeightType::volume)
207 {
208 lxad *= volume;
209 lwad.format(volume);
210 }
211
212 // prepare dof-mapping
213 dof_mapping.prepare(cell);
214
215 // incorporate local vector and weights
216 scatter_axpy(lxad, dof_mapping);
217 weight_scatter_axpy(lwad, dof_mapping);
218
219 // finish dof-mapping
220 dof_mapping.finish();
221 }
222
223 // finally, scale the vector by the weights
224 DataType* vx(vector.elements());
225 DataType* wx(weight.elements());
226 for(Index i(0); i < num_dofs; ++i)
227 {
228 if(wx[i] > DataType(0))
229 vx[i] /= wx[i];
230 }
231
232 // okay
233 }
234 }; // class RewProjector
235 } // namespace Assembly
236} // namespace FEAT
Common single-space assembly traits class template.
Definition: asm_traits.hpp:83
Restricted Element-Wise Projection operator.
WeightType
Weighting type enumeration.
@ volume
use volume-based averaging
@ arithmetic
use arithmetic averaging
static void project(LAFEM::DenseVector< DT_, IT_ > &vector, const Function_ &function, const Space_ &space, const CubatureFactory_ &cubature_factory, WeightType weight_type=WeightType::volume)
Projects an analytic function into a finite element space.
Dense data vector class template.
DT_ * elements()
Get a pointer to the data array.
DT_ invert_matrix(const IT_ n, const IT_ stride, DT_ a[], IT_ p[])
Inverts a matrix and returns its determinant.
Definition: math.hpp:1292
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.