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>
67 typename CubatureFactory_>
70 const Function_& function,
72 const CubatureFactory_& cubature_factory,
76 typedef Function_ FunctionType;
77 typedef Space_ SpaceType;
78 typedef typename SpaceType::TrafoType TrafoType;
80 static_assert(Function_::can_value,
"analytic function can't compute function values");
84 typedef typename AsmTraits::DataType DataType;
87 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
90 const TrafoType& trafo(space.get_trafo());
93 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
96 typename AsmTraits::SpaceEvaluator space_eval(space);
99 typename AsmTraits::DofMapping dof_mapping(space);
105 typename FunctionType::template Evaluator<AnalyticEvalTraits> func_eval(function);
108 typename AsmTraits::TrafoEvalData trafo_data;
111 typename AsmTraits::SpaceEvalData space_data;
114 typename AsmTraits::template TLocalMatrix<DT_> mass;
120 typename AsmTraits::template TLocalVector<DT_> lvad, lxad;
123 typename AsmTraits::template TLocalVector<DT_> lwad;
126 const Index num_dofs(space.get_num_dofs());
129 vector = VectorType(num_dofs, DataType(0));
132 VectorType weight(num_dofs, DataType(0));
135 typename VectorType::ScatterAxpy scatter_axpy(vector);
138 typename VectorType::ScatterAxpy weight_scatter_axpy(weight);
142 lwad.format(DataType(1));
145 for(
Index cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
148 trafo_eval.prepare(cell);
151 space_eval.prepare(trafo_eval);
154 int num_loc_dofs(space_eval.get_num_local_dofs());
161 DataType
volume(DataType(0));
164 for(
int k(0); k < cubature_rule.get_num_points(); ++k)
167 trafo_eval(trafo_data, cubature_rule.get_point(k));
170 space_eval(space_data, trafo_data);
173 DataType fv = func_eval.value(trafo_data.img_point);
176 DataType omega(trafo_data.jac_det * cubature_rule.get_weight(k));
182 for(
int i(0); i < num_loc_dofs; ++i)
185 lvad(i) += omega * fv * space_data.phi[i].value;
188 for(
int j(0); j < num_loc_dofs; ++j)
190 mass(i,j) += omega * space_data.phi[i].value * space_data.phi[j].value;
203 lxad.set_mat_vec_mult(mass, lvad);
213 dof_mapping.prepare(cell);
216 scatter_axpy(lxad, dof_mapping);
217 weight_scatter_axpy(lwad, dof_mapping);
220 dof_mapping.finish();
225 DataType* wx(weight.elements());
226 for(
Index i(0); i < num_dofs; ++i)
228 if(wx[i] > DataType(0))
Common single-space assembly traits class template.
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.
std::uint64_t Index
Index data type.