FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
scalar_basic.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
9#include <kernel/util/dist.hpp>
10#include <kernel/cubature/dynamic_factory.hpp>
11#include <kernel/lafem/dense_vector.hpp>
12#include <kernel/lafem/sparse_matrix_csr.hpp>
13#include <kernel/lafem/unit_filter.hpp>
14#include <kernel/lafem/mean_filter.hpp>
15#include <kernel/lafem/none_filter.hpp>
16#include <kernel/lafem/filter_chain.hpp>
17#include <kernel/lafem/filter_sequence.hpp>
18#include <kernel/lafem/vector_mirror.hpp>
19#include <kernel/lafem/transfer.hpp>
20#include <kernel/global/gate.hpp>
21#include <kernel/global/muxer.hpp>
22#include <kernel/global/vector.hpp>
23#include <kernel/global/matrix.hpp>
24#include <kernel/global/transfer.hpp>
25#include <kernel/global/splitter.hpp>
26#include <kernel/global/filter.hpp>
27#include <kernel/global/mean_filter.hpp>
28#include <kernel/assembly/common_operators.hpp>
29#include <kernel/assembly/symbolic_assembler.hpp>
30#include <kernel/assembly/domain_assembler_basic_jobs.hpp>
31#include <kernel/assembly/bilinear_operator_assembler.hpp>
32#include <kernel/assembly/grid_transfer.hpp>
33#include <kernel/assembly/mirror_assembler.hpp>
34#include <kernel/assembly/mean_filter_assembler.hpp>
35#include <kernel/assembly/unit_filter_assembler.hpp>
36#include <kernel/analytic/lambda_function.hpp>
37#include <kernel/solver/base.hpp>
38#include <kernel/solver/iterative.hpp>
39#include <kernel/util/property_map.hpp>
40#include <kernel/voxel_assembly/poisson_assembler.hpp>
41
42#include <control/domain/domain_control.hpp>
43#include <control/domain/adaptive_parti_domain_control.hpp>
44#include <control/asm/gate_asm.hpp>
45#include <control/asm/muxer_asm.hpp>
46#include <control/asm/splitter_asm.hpp>
47#include <control/asm/transfer_adaptive_asm.hpp>
48#include <control/asm/transfer_asm.hpp>
49#include <control/asm/transfer_voxel_asm.hpp>
50#include <control/asm/mean_filter_asm.hpp>
51#include <control/asm/unit_filter_asm.hpp>
52
53#include <deque>
54
55namespace FEAT
56{
57 namespace Control
58 {
59 template<
60 typename DataType_ = Real,
61 typename IndexType_ = Index,
62 typename ScalarMatrix_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_>,
63 typename TransferMatrix_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_> >
65 {
66 public:
67 static_assert(std::is_same<DataType_, typename ScalarMatrix_::DataType>::value, "DataType mismatch!");
68 static_assert(std::is_same<IndexType_, typename ScalarMatrix_::IndexType>::value, "IndexType mismatch!");
69
70 // basic types
71 typedef DataType_ DataType;
72 typedef IndexType_ IndexType;
73
75 typedef ScalarMatrix_ LocalScalarMatrix;
76
78 typedef ScalarMatrix_ LocalSystemMatrix;
79
81 typedef TransferMatrix_ LocalSystemTransferMatrix;
82
84 typedef typename LocalSystemMatrix::VectorTypeR LocalSystemVector;
85
88
91
94
97
100
103
106
109
110 /* ***************************************************************************************** */
111
114
117
120
123
126
131 {
132 }
133
134 // no copies, no problems
136 ScalarBasicSystemLevel& operator=(const ScalarBasicSystemLevel&) = delete;
137
139 {
140 }
141
143 std::size_t bytes() const
144 {
145 return this->gate_sys.bytes() + this->coarse_muxer_sys.bytes() + this->base_splitter_sys.bytes()
146 + this->transfer_sys.bytes() + this->matrix_sys.local().bytes();
147 }
148
149 template<typename D_, typename I_, typename SM_>
150 void convert(const ScalarBasicSystemLevel<D_, I_, SM_> & other)
151 {
152 gate_sys.convert(other.gate_sys);
153 coarse_muxer_sys.convert(other.coarse_muxer_sys);
154 base_splitter_sys.convert(other.base_splitter_sys);
155 matrix_sys.convert(&gate_sys, &gate_sys, other.matrix_sys);
156 transfer_sys.convert(&coarse_muxer_sys, other.transfer_sys);
157 }
158
159 template<typename DomainLevel_, typename SpaceType_>
160 void assemble_gate(const Domain::VirtualLevel<DomainLevel_>& virt_dom_lvl, const SpaceType_& space)
161 {
162 Asm::asm_gate(virt_dom_lvl, space, this->gate_sys, true);
163 }
164
165 template<typename DomainLevel_>
166 void assemble_gate(const Domain::VirtualLevel<DomainLevel_>& virt_dom_lvl)
167 {
168 Asm::asm_gate(virt_dom_lvl, virt_dom_lvl->space, this->gate_sys, true);
169 }
170
171 template<typename DomainLevel_>
172 void assemble_coarse_muxer(const Domain::VirtualLevel<DomainLevel_>& virt_lvl_coarse)
173 {
174 Asm::asm_muxer(virt_lvl_coarse, [](const DomainLevel_& dl){return &dl.space;}, this->coarse_muxer_sys);
175 }
176
177 template<typename DomainLevel_>
178 void assemble_base_splitter(const Domain::VirtualLevel<DomainLevel_>& virt_lvl)
179 {
180 Asm::asm_splitter(virt_lvl, [](const DomainLevel_& dl){return &dl.space;}, this->base_splitter_sys);
181 }
182
183 template<typename DomainLevel_>
184 void assemble_transfer(
185 const ScalarBasicSystemLevel& sys_lvl_coarse,
186 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_fine,
187 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_coarse,
188 const String& cubature, bool trunc = false, bool shrink = true)
189 {
190 Asm::asm_transfer_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc, shrink,
191 [](const DomainLevel_& dl) {return &dl.space;},
192 this->transfer_sys.local(), this->coarse_muxer_sys, this->gate_sys, sys_lvl_coarse.gate_sys);
193
194 this->transfer_sys.compile();
195 }
196
197 template<typename DomainLevel_>
198 void assemble_transfer(
199 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_fine,
200 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_coarse,
201 const String& cubature, bool trunc = false, bool shrink = true)
202 {
203 // if the coarse level is a parent, then we need the coarse system level
204 XASSERT(!virt_lvl_coarse.is_parent());
205
206 Asm::asm_transfer_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc, shrink,
207 [](const DomainLevel_& dl) {return &dl.space;},
208 this->transfer_sys.local(), this->coarse_muxer_sys, this->gate_sys, this->gate_sys);
209
210 this->transfer_sys.compile();
211 }
212
213 template<typename DomainLevel_>
214 void assemble_transfer_voxel(
215 const ScalarBasicSystemLevel& sys_lvl_coarse,
216 const Domain::VirtualLevel<Domain::VoxelDomainLevelWrapper<DomainLevel_>>& virt_lvl_fine,
217 const Domain::VirtualLevel<Domain::VoxelDomainLevelWrapper<DomainLevel_>>& virt_lvl_coarse,
218 const String& cubature, bool trunc = false, bool shrink = true)
219 {
220 Asm::asm_transfer_voxel_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc, shrink,
221 [](const DomainLevel_& dl) {return &dl.space;},
222 this->transfer_sys.local(), this->coarse_muxer_sys, this->gate_sys, sys_lvl_coarse.gate_sys);
223
224 this->transfer_sys.compile();
225 }
226
227 template<typename DomainLevel_>
228 void assemble_transfer_voxel(
229 const Domain::VirtualLevel<Domain::VoxelDomainLevelWrapper<DomainLevel_>>& virt_lvl_fine,
230 const Domain::VirtualLevel<Domain::VoxelDomainLevelWrapper<DomainLevel_>>& virt_lvl_coarse,
231 const String& cubature, bool trunc = false, bool shrink = true)
232 {
233 // if the coarse level is a parent, then we need the coarse system level
234 XASSERT(!virt_lvl_coarse.is_parent());
235
236 Asm::asm_transfer_voxel_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc, shrink,
237 [](const DomainLevel_& dl) {return &dl.space;},
238 this->transfer_sys.local(), this->coarse_muxer_sys, this->gate_sys, this->gate_sys);
239
240 this->transfer_sys.compile();
241 }
242
243 template<typename DomainLevel_, typename TemplateSet_>
244 void assemble_transfer_adaptive(
245 const ScalarBasicSystemLevel& sys_lvl_coarse,
246 const Domain::VirtualLevel<Domain::AdaptiveLevelWrapper<DomainLevel_, TemplateSet_>>& virt_lvl_fine,
247 const Domain::VirtualLevel<Domain::AdaptiveLevelWrapper<DomainLevel_, TemplateSet_>>& virt_lvl_coarse,
248 const String& cubature, bool trunc = false, bool shrink = true)
249 {
250 Asm::asm_transfer_adaptive_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc, shrink,
251 [](const DomainLevel_& dl) {return &dl.space;},
252 this->transfer_sys.local(), this->coarse_muxer_sys, this->gate_sys, sys_lvl_coarse.gate_sys);
253
254 this->transfer_sys.compile();
255 }
256
257 template<typename DomainLevel_, typename TemplateSet_>
258 void assemble_transfer_adaptive(
259 const Domain::VirtualLevel<Domain::AdaptiveLevelWrapper<DomainLevel_, TemplateSet_>>& virt_lvl_fine,
260 const Domain::VirtualLevel<Domain::AdaptiveLevelWrapper<DomainLevel_, TemplateSet_>>& virt_lvl_coarse,
261 const String& cubature, bool trunc = false, bool shrink = true)
262 {
263 // if the coarse level is a parent, then we need the coarse system level
264 XASSERT(!virt_lvl_coarse.is_parent());
265
266 Asm::asm_transfer_adaptive_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc, shrink,
267 [](const DomainLevel_& dl) {return &dl.space;},
268 this->transfer_sys.local(), this->coarse_muxer_sys, this->gate_sys, this->gate_sys);
269
270 this->transfer_sys.compile();
271 }
272
273 template<typename Space_, typename Cubature_>
274 void assemble_laplace_matrix(const Space_& space, const Cubature_& cubature, const DataType nu = DataType(1))
275 {
276 // get local matrix
277 auto& loc_matrix = this->matrix_sys.local();
278
279 // assemble structure?
280 if(loc_matrix.empty())
281 {
283 }
284
285 // format and assemble Laplace
286 loc_matrix.format();
287 Assembly::Common::LaplaceOperator laplace_op;
288 Assembly::BilinearOperatorAssembler::assemble_matrix1(loc_matrix, laplace_op, space, cubature, nu);
289 }
290
291 template<typename Trafo_, typename Space_>
292 void assemble_laplace_matrix(Assembly::DomainAssembler<Trafo_>& dom_asm, const Space_& space, const String& cubature, const DataType nu = DataType(1))
293 {
294 // get local matrix
295 auto& loc_matrix = this->matrix_sys.local();
296
297 // assemble structure?
298 if(loc_matrix.empty())
299 {
301 }
302
303 // format and assemble Laplace
304 loc_matrix.format();
305 Assembly::Common::LaplaceOperator laplace_op;
306 Assembly::assemble_bilinear_operator_matrix_1(dom_asm, loc_matrix, laplace_op, space, cubature, nu);
307 }
308
309 template<typename Space_>
310 void assemble_laplace_voxel_based(const Adjacency::Coloring& coloring, const Space_& space, const String& cubature, const DataType nu = DataType(1))
311 {
312 // get local matrix
313 auto& loc_matrix = this->matrix_sys.local();
314
315 // assemble structure?
316 if(loc_matrix.empty())
317 {
319 }
320
321 // format and assemble Laplace
322 loc_matrix.format();
323 VoxelAssembly::VoxelPoissonAssembler<Space_, DataType, IndexType> voxel_assembler(space, coloring);
324 voxel_assembler.assemble_matrix1(loc_matrix, space, Cubature::DynamicFactory(cubature), nu);
325 }
326
327 template<typename Space_>
328 void symbolic_assembly_std1(const Space_& space)
329 {
330 // get local matrix
331 auto& loc_matrix = this->matrix_sys.local();
332
333 ASSERTM(loc_matrix.empty(), "Called symbolic assembly on non empty matrix");
334 // assemble structure?
336
337 }
338 }; // class ScalarBasicSystemLevel<...>
339
340 template<
341 typename DataType_ = Real,
342 typename IndexType_ = Index,
343 typename ScalarMatrix_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_> >
345 public ScalarBasicSystemLevel<DataType_, IndexType_, ScalarMatrix_>
346 {
347 public:
349
350 // basic types
351 typedef DataType_ DataType;
352 typedef IndexType_ IndexType;
353
356
359
362
364 template <typename DT2_, typename IT2_, typename ScalarMatrix2_>
366
369
372 BaseClass()
373 {
374 }
375
377 std::size_t bytes() const
378 {
379 return BaseClass::bytes() + this->filter_sys.local().bytes();
380 }
381
389 template<typename D_, typename I_, typename SM_>
391 {
392 BaseClass::convert(other);
393 filter_sys.convert(other.filter_sys);
394 }
395
396 template<typename DomainLevel_, typename Space_>
397 void assemble_homogeneous_unit_filter(const DomainLevel_& dom_level, const Space_& space)
398 {
399 Asm::asm_unit_filter_scalar_homogeneous(this->filter_sys.local(), dom_level, space, "*");
400 }
401
402 }; // class ScalarUnitFilterSystemLevel<...>
403
404 template<
405 typename DataType_ = Real,
406 typename IndexType_ = Index,
407 typename ScalarMatrix_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_> >
409 public ScalarBasicSystemLevel<DataType_, IndexType_, ScalarMatrix_>
410 {
411 public:
413
414 // basic types
415 typedef DataType_ DataType;
416 typedef IndexType_ IndexType;
417
420
423
426
428 template <typename DT2_, typename IT2_, typename ScalarMatrix2_>
430
433
436 BaseClass()
437 {
438 }
439
441 std::size_t bytes() const
442 {
443 return BaseClass::bytes() + this->filter_sys.local().bytes();
444 }
445
453 template<typename D_, typename I_, typename SM_>
455 {
456 BaseClass::convert(other);
457 filter_sys.convert(other.filter_sys);
458 }
459
460 template<typename Space_, typename Cubature_>
461 void assemble_mean_filter(const Space_& space, const Cubature_& cubature)
462 {
463 this->filter_sys.local() = Asm::asm_mean_filter(this->gate_sys, space, cubature);
464 }
465 }; // class ScalarMeanFilterSystemLevel<...>
466
467 template<
468 typename DataType_ = Real,
469 typename IndexType_ = Index,
470 typename ScalarMatrix_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_> >
472 public ScalarBasicSystemLevel<DataType_, IndexType_, ScalarMatrix_>
473 {
474 public:
476
477 // basic types
478 typedef DataType_ DataType;
479 typedef IndexType_ IndexType;
480
483
489
492
494 template <typename DT2_, typename IT2_, typename ScalarMatrix2_>
496
499
502 BaseClass()
503 {
504 }
505
507 std::size_t bytes() const
508 {
509 return BaseClass::bytes() + this->filter_sys.local().bytes();
510 }
511
512 template<typename D_, typename I_, typename SM_>
513 void convert(const ScalarMeanFilterSystemLevel<D_, I_, SM_> & other)
514 {
515 BaseClass::convert(other);
516 filter_sys.convert(other.filter_sys);
517 }
518
519 LocalUnitFilterSeq& get_local_unit_filter_seq()
520 {
521 return this->filter_sys.local().template at<0>();
522 }
523
524 LocalUnitFilter& get_local_unit_filter(const String& name)
525 {
526 return get_local_unit_filter_seq().find_or_add(name);
527 }
528
529 LocalMeanFilter& get_local_mean_filter()
530 {
531 return this->filter_sys.local().template at<1>();
532 }
533
534 template<typename DomainLevel_, typename Space_>
535 void assemble_unit_filter(const DomainLevel_& dom_level, const Space_& space, const String& name, const String& mesh_part_names)
536 {
537 auto& loc_filter = get_local_unit_filter(name);
538 loc_filter.clear();
539 Asm::asm_unit_filter_scalar_homogeneous(loc_filter, dom_level, space, mesh_part_names);
540 }
541
542 template<typename DomainLevel_, typename Space_, typename Function_>
543 void assemble_unit_filter(const DomainLevel_& dom_level, const Space_& space, const String& name, const String& mesh_part_names, const Function_& function)
544 {
545 auto& loc_filter = get_local_unit_filter(name);
546 loc_filter.clear();
547 Asm::asm_unit_filter_scalar(loc_filter, dom_level, space, mesh_part_names, function);
548 }
549
550 template<typename Space_>
551 void assemble_mean_filter(const Space_& space, const String& cubature)
552 {
553 get_local_mean_filter() = Asm::asm_mean_filter(this->gate_sys, space, cubature);
554 }
555 }; // class ScalarCombinedSystemLevel<...>
556 } // namespace Control
557} // namespace FEAT
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
Definition: assertion.hpp:230
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
FEAT Kernel base header.
static void assemble_matrix1(Matrix_ &matrix, Operator_ &operat, const Space_ &space, const CubatureFactory_ &cubature_factory, typename Matrix_::DataType alpha=typename Matrix_::DataType(1))
Assembles a bilinear operator into a matrix.
static void assemble_matrix_std1(MatrixType_ &matrix, const Space_ &space)
Assembles a standard matrix structure from a single space.
Global::Muxer< LocalSystemVector, SystemMirror > SystemMuxer
define system muxer
LocalSystemMatrix::VectorTypeR LocalSystemVector
define local system vector type
LAFEM::Transfer< LocalSystemTransferMatrix > LocalSystemTransfer
define local system transfer operator type
SystemGate gate_sys
our system gate
Global::Transfer< LocalSystemTransfer, SystemMirror > GlobalSystemTransfer
define global system transfer operator type
std::size_t bytes() const
Returns the total amount of bytes allocated.
SystemSplitter base_splitter_sys
our base-mesh multiplexer
ScalarMatrix_ LocalScalarMatrix
define local scalar matrix type
LAFEM::VectorMirror< DataType, IndexType > SystemMirror
define system mirror type
TransferMatrix_ LocalSystemTransferMatrix
define local transfer matrix type
GlobalSystemTransfer transfer_sys
our global transfer operator
SystemMuxer coarse_muxer_sys
our coarse-level system muxer
Global::Matrix< LocalSystemMatrix, SystemMirror, SystemMirror > GlobalSystemMatrix
define global system matrix type
Global::Vector< LocalSystemVector, SystemMirror > GlobalSystemVector
define global system vector type
Global::Gate< LocalSystemVector, SystemMirror > SystemGate
define system gate
Global::Splitter< LocalSystemVector, SystemMirror > SystemSplitter
define system splitter
GlobalSystemMatrix matrix_sys
our global system matrix
ScalarMatrix_ LocalSystemMatrix
define local system matrix type
Global::Filter< LocalSystemFilter, SystemMirror > GlobalSystemFilter
define global filter types
LAFEM::VectorMirror< DataType, IndexType > SystemMirror
define system mirror type
std::size_t bytes() const
Returns the total amount of bytes allocated.
GlobalSystemFilter filter_sys
our global system filter
LAFEM::UnitFilter< DataType, IndexType > LocalUnitFilter
define local filter types
GlobalSystemFilter filter_sys
our global system filter
Global::Filter< LocalSystemFilter, SystemMirror > GlobalSystemFilter
define global filter type
Global::MeanFilter< DataType_, IndexType_ > LocalSystemFilter
define local filter type
std::size_t bytes() const
Returns the total amount of bytes allocated.
void convert(const ScalarMeanFilterSystemLevel< D_, I_, SM_ > &other)
Conversion method.
LAFEM::VectorMirror< DataType, IndexType > SystemMirror
define system mirror type
LAFEM::VectorMirror< DataType, IndexType > SystemMirror
define system mirror type
Global::Filter< LocalSystemFilter, SystemMirror > GlobalSystemFilter
define global filter type
std::size_t bytes() const
Returns the total amount of bytes allocated.
LAFEM::UnitFilter< DataType_, IndexType_ > LocalSystemFilter
define local filter type
GlobalSystemFilter filter_sys
our global system filter
void convert(const ScalarUnitFilterSystemLevel< D_, I_, SM_ > &other)
Conversion method.
Global Filter wrapper class template.
Definition: filter.hpp:21
Global gate implementation.
Definition: gate.hpp:51
void convert(const Gate< LVT2_, MT2_ > &other)
Conversion function for same vector container type but with different MDI-Type.
Definition: gate.hpp:191
std::size_t bytes() const
Returns the total amount of bytes allocated.
Definition: gate.hpp:252
Global Matrix wrapper class template.
Definition: matrix.hpp:40
LocalMatrix_ & local()
Returns a reference to the internal local LAFEM matrix object.
Definition: matrix.hpp:126
Mean Filter class template.
Definition: mean_filter.hpp:23
Global multiplexer/demultiplexer implementation.
Definition: muxer.hpp:68
std::size_t bytes() const
Returns the internal data size in bytes.
Definition: muxer.hpp:211
void convert(const Muxer< LVT2_, MT2_ > &other)
Conversion function for same vector container type but with different MDI-Type.
Definition: muxer.hpp:155
Global base-mesh vector splitter (and joiner) implementation.
Definition: splitter.hpp:59
std::size_t bytes() const
Returns the internal data size in bytes.
Definition: splitter.hpp:163
void convert(const Splitter< LVT2_, MT2_ > &other)
Conversion function for same vector container type but with different MDI-Type.
Definition: splitter.hpp:124
Global grid-transfer operator class template.
Definition: transfer.hpp:23
void convert(MuxerType *coarse_muxer, const Transfer< LocalTransfer2_, Mirror2_ > &other)
container conversion function
Definition: transfer.hpp:107
std::size_t bytes() const
Definition: transfer.hpp:143
LocalTransfer_ & local()
Definition: transfer.hpp:131
Global vector wrapper class template.
Definition: vector.hpp:68
Filter Chainclass template.
std::size_t bytes() const
Returns the total amount of bytes allocated.
Sequence of filters of the same type.
Grid-Transfer operator class template.
Definition: transfer.hpp:27
Unit Filter class template.
Definition: unit_filter.hpp:29
std::size_t bytes() const
Returns the total amount of bytes allocated.
Handles vector prolongation, restriction and serialization.
void assemble_bilinear_operator_matrix_1(DomainAssembler< Trafo_ > &dom_asm, Matrix_ &matrix, const BilOp_ &bilinear_operator, const Space_ &space, const String &cubature, const typename Matrix_::DataType alpha=typename Matrix_::DataType(1))
Assembles a bilinear operator into a matrix with identical test- and trial-spaces.
FEAT namespace.
Definition: adjactor.hpp:12
double Real
Real data type.
std::uint64_t Index
Index data type.