FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
grad_operator_assembler.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
7#pragma once
8
9#include <kernel/assembly/asm_traits.hpp>
10#include <kernel/assembly/symbolic_assembler.hpp>
11#include <kernel/lafem/sparse_matrix_bcsr.hpp>
12
13namespace FEAT
14{
15 namespace Assembly
16 {
27 {
28 public:
29
66 template<typename DT_, typename IT_, int dim_,
67 typename SpaceTest_, typename SpaceTrial_,
68 typename CubatureFactory_>
69 static void assemble(
71 const SpaceTest_& test_space,
72 const SpaceTrial_& trial_space,
73 const CubatureFactory_& cubature_factory,
74 const DT_ scale = DT_(1)
75 )
76 {
77 typedef DT_ DataType;
78 typedef IT_ IndexType;
79 static constexpr int dim = dim_;
80
81 // ensure that the matrices have the correct dimensions
82 static_assert(SpaceTest_::shape_dim == dim_, "invalid matrix block sizes");
83
84 // make sure that trial and test spaces have the same trafo
85 XASSERTM((&test_space.get_trafo()) == (&trial_space.get_trafo()),
86 "Trial and test spaces must be defined on the same trafo!");
87
89
90 // assembly traits
91 typedef AsmTraits2<
92 DataType,
93 SpaceTest_,
94 SpaceTrial_,
97 SpaceTags::grad> AsmTraits;
98
99 // fetch the trafo
100 const typename AsmTraits::TrafoType& trafo = test_space.get_trafo();
101
102 // create a trafo evaluator
103 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
104
105 // create space evaluators
106 typename AsmTraits::TestEvaluator test_eval(test_space);
107 typename AsmTraits::TrialEvaluator trial_eval(trial_space);
108
109 // create dof-mappings
110 typename AsmTraits::TestDofMapping test_dof_mapping(test_space);
111 typename AsmTraits::TrialDofMapping trial_dof_mapping(trial_space);
112
113 // create trafo evaluation data
114 typename AsmTraits::TrafoEvalData trafo_data;
115
116 // create space evaluation data
117 typename AsmTraits::TestEvalData test_data;
118 typename AsmTraits::TrialEvalData trial_data;
119
120 // maximum number of dofs
121 static constexpr int max_test_dofs = AsmTraits::max_local_test_dofs;
122 static constexpr int max_trial_dofs = AsmTraits::max_local_trial_dofs;
123
124 // create local matrix data
125 //typename AsmTraits::LocalMatrixType lmd;
126 typedef Tiny::Matrix<DataType, dim, 1> GEntryType;
128
129 // create cubature rule
130 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
131
132 // first of all, check whether we need to assemble the matrix structures
133 if(matrix_g.empty())
134 {
135 Adjacency::Graph graph_g(SymbolicAssembler::assemble_graph_std2(test_space, trial_space));
136 matrix_g = MatrixG(graph_g);
137 }
138 matrix_g.format();
139
140 // create matrix scatter-axpy (if needed)
141 typename MatrixG::ScatterAxpy scatter_matrix(matrix_g);
142
143 // loop over all cells of the mesh
144 for(typename AsmTraits::CellIterator cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
145 {
146 // prepare trafo evaluator
147 trafo_eval.prepare(cell);
148
149 // prepare space evaluators
150 test_eval.prepare(trafo_eval);
151 trial_eval.prepare(trafo_eval);
152
153 // fetch number of local dofs
154 const int num_loc_test_dofs = test_eval.get_num_local_dofs();
155 const int num_loc_trial_dofs = trial_eval.get_num_local_dofs();
156
157 // format local matrix and vector
158 local_matrix.format();
159
160 // loop over all quadrature points and integrate
161 for(int pt(0); pt < cubature_rule.get_num_points(); ++pt)
162 {
163 // compute trafo data
164 trafo_eval(trafo_data, cubature_rule.get_point(pt));
165
166 // compute basis function data
167 test_eval(test_data, trafo_data);
168 trial_eval(trial_data, trafo_data);
169
170 // trial function loop
171 for(int i(0); i < num_loc_test_dofs; ++i)
172 {
173 // test function loop
174 for(int j(0); j < num_loc_trial_dofs; ++j)
175 {
176 const DataType pv = trafo_data.jac_det * cubature_rule.get_weight(pt) * test_data.phi[i].value;
177
178 // dimension loop
179 for(int k(0); k < dim; ++k)
180 {
181 local_matrix[i][j][k][0] += trial_data.phi[j].grad[k] * pv;
182 }
183
184 // continue with next trial function
185 }
186 // continue with next test function
187 }
188 // continue with next cubature point
189 }
190
191 // finish evaluators
192 trial_eval.finish();
193 test_eval.finish();
194 trafo_eval.finish();
195
196 // initialize dof-mappings
197 test_dof_mapping.prepare(cell);
198 trial_dof_mapping.prepare(cell);
199
200 // scatter into matrix
201 scatter_matrix(local_matrix, test_dof_mapping, trial_dof_mapping, scale);
202
203 // finish dof mapping
204 trial_dof_mapping.finish();
205 test_dof_mapping.finish();
206
207 // continue with next cell
208 }
209 }
210
250 template<typename DT_, typename IT_, int dim_,
251 typename SpaceTest_, typename SpaceTrial_,
252 typename CubatureFactory_>
253 static void assemble(
255 const LAFEM::DenseVector<DT_, IT_>& vec_in,
256 const SpaceTest_& test_space,
257 const SpaceTrial_& trial_space,
258 const CubatureFactory_& cubature_factory,
259 const DT_ scale = DT_(1)
260 )
261 {
262 typedef DT_ DataType;
263 typedef IT_ IndexType;
264 static constexpr int dim = dim_;
265
266 // ensure that the matrices have the correct dimensions
267 static_assert(SpaceTest_::shape_dim == dim, "invalid matrix block sizes");
268
269 // make sure that trial and test spaces have the same trafo
270 XASSERTM((&test_space.get_trafo()) == (&trial_space.get_trafo()),
271 "Trial and test spaces must be defined on the same trafo!");
272
275
276 // assembly traits
277 typedef AsmTraits2<
278 DataType,
279 SpaceTest_,
280 SpaceTrial_,
283 SpaceTags::grad> AsmTraits;
284
285 // fetch the trafo
286 const typename AsmTraits::TrafoType& trafo = test_space.get_trafo();
287
288 // create a trafo evaluator
289 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
290
291 // create space evaluators
292 typename AsmTraits::TestEvaluator test_eval(test_space);
293 typename AsmTraits::TrialEvaluator trial_eval(trial_space);
294
295 // create dof-mappings
296 typename AsmTraits::TestDofMapping test_dof_mapping(test_space);
297 typename AsmTraits::TrialDofMapping trial_dof_mapping(trial_space);
298
299 // create trafo evaluation data
300 typename AsmTraits::TrafoEvalData trafo_data;
301
302 // create space evaluation data
303 typename AsmTraits::TestEvalData test_data;
304 typename AsmTraits::TrialEvalData trial_data;
305
306 // maximum number of dofs
307 static constexpr int max_test_dofs = AsmTraits::max_local_test_dofs;
308 static constexpr int max_trial_dofs = AsmTraits::max_local_trial_dofs;
309
310 // create local vector data
311 typedef Tiny::Vector<DataType, dim> VectorValue;
312 typedef Tiny::Vector<VectorValue, max_test_dofs> LocalVectorType;
313 LocalVectorType local_vector;
314
315 typedef Tiny::Vector<DataType, max_trial_dofs> LocalVecInType;
316 LocalVecInType local_vec_in_dofs;
317
318 // our local trial function gradient
319 Tiny::Vector<DataType, dim> loc_grad_trial;
320
321 // create cubature rule
322 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
323
324 // Create vector-scatter-axpy for the vector to be assembled
325 typename VectorAsm::ScatterAxpy scatter_vector(vec_asm);
326 // Create vector gather axpy for the input vector
327 typename VectorIn::GatherAxpy gather_vec_in(vec_in);
328
329 // loop over all cells of the mesh
330 for(typename AsmTraits::CellIterator cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
331 {
332 // prepare trafo evaluator
333 trafo_eval.prepare(cell);
334
335 // prepare space evaluators
336 test_eval.prepare(trafo_eval);
337 trial_eval.prepare(trafo_eval);
338
339 // Initialize trial DoF mapping
340 trial_dof_mapping.prepare(cell);
341
342 // Gather our local input DoF
343 local_vec_in_dofs.format();
344 gather_vec_in(local_vec_in_dofs, trial_dof_mapping);
345
346 // fetch number of local dofs
347 const int num_loc_test_dofs = test_eval.get_num_local_dofs();
348 const int num_loc_trial_dofs = trial_eval.get_num_local_dofs();
349
350 // format local matrix and vector
351 local_vector.format();
352
353 // loop over all quadrature points and integrate
354 for(int pt(0); pt < cubature_rule.get_num_points(); ++pt)
355 {
356 // compute trafo data
357 trafo_eval(trafo_data, cubature_rule.get_point(pt));
358
359 // compute basis function data
360 test_eval(test_data, trafo_data);
361 trial_eval(trial_data, trafo_data);
362
363 // evaluate trial function gradient
364 loc_grad_trial.format();
365 for(int i(0); i < num_loc_trial_dofs; ++i)
366 {
367 for(int k(0); k < dim; ++k)
368 {
369 loc_grad_trial[k] += local_vec_in_dofs[i] * trial_data.phi[i].grad[k];
370 }
371 }
372
373 // test function loop
374 for(int i(0); i < num_loc_test_dofs; ++i)
375 {
376 const DataType v(trafo_data.jac_det * cubature_rule.get_weight(pt) * test_data.phi[i].value);
377
378 // dimension loop
379 for(int k(0); k < dim; ++k)
380 {
381 //local_matrix[i][j][k][0] += test_data.phi[i].grad[k] * pv;
382 // update vector
383 local_vector[i][k] += v * loc_grad_trial[k];
384 }
385 } // continue with next test function
386
387 }// continue with next cubature point
388
389 // finish evaluators
390 trial_eval.finish();
391 test_eval.finish();
392 trafo_eval.finish();
393
394 // Initialize test DoF mapping
395 test_dof_mapping.prepare(cell);
396
397 // scatter into vector
398 scatter_vector(local_vector, test_dof_mapping, scale);
399
400 // Finish all DoF mappings
401 trial_dof_mapping.finish();
402 test_dof_mapping.finish();
403
404 } // continue with next cell
405 }
406
407 };
408 } // namespace Assembly
409} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Adjacency Graph implementation.
Definition: graph.hpp:34
Common test-/trial-space assembly traits class template.
Definition: asm_traits.hpp:227
static void assemble(LAFEM::SparseMatrixBCSR< DT_, IT_, dim_, 1 > &matrix_g, const SpaceTest_ &test_space, const SpaceTrial_ &trial_space, const CubatureFactory_ &cubature_factory, const DT_ scale=DT_(1))
Assembles the bilinear form into a matrix.
static void assemble(LAFEM::DenseVectorBlocked< DT_, IT_, dim_ > &vec_asm, const LAFEM::DenseVector< DT_, IT_ > &vec_in, const SpaceTest_ &test_space, const SpaceTrial_ &trial_space, const CubatureFactory_ &cubature_factory, const DT_ scale=DT_(1))
Assembles the application of the bilinear form to a vector into a vector.
static Adjacency::Graph assemble_graph_std2(const TestSpace_ &test_space, const TrialSpace_ &trial_space)
Assembles the standard Dof-Adjacency graph for different test- and trial-spaces.
bool empty() const
Checks whether the container is empty.
Definition: container.hpp:1165
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
Definition: container.hpp:851
Blocked Dense data vector class template.
Dense data vector class template.
CSR based blocked sparse matrix.
Tiny Matrix class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the vector.
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
@ grad
specifies whether the space should supply basis function gradients
@ jac_det
specifies whether the trafo should supply jacobian determinants