FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
scalar_mixed.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/lafem/dense_vector.hpp>
10#include <kernel/lafem/dense_vector_blocked.hpp>
11#include <kernel/lafem/filter_chain.hpp>
12#include <kernel/lafem/sparse_matrix_csr.hpp>
13#include <kernel/lafem/sparse_matrix_bcsr.hpp>
14#include <kernel/lafem/sparse_matrix_bwrappedcsr.hpp>
15#include <kernel/lafem/saddle_point_matrix.hpp>
16//#include <kernel/lafem/mean_filter.hpp>
17#include <kernel/lafem/filter_sequence.hpp>
18#include <kernel/lafem/none_filter.hpp>
19#include <kernel/lafem/slip_filter.hpp>
20#include <kernel/lafem/tuple_filter.hpp>
21#include <kernel/lafem/tuple_mirror.hpp>
22#include <kernel/lafem/tuple_diag_matrix.hpp>
23#include <kernel/lafem/transfer.hpp>
24#include <kernel/assembly/mirror_assembler.hpp>
25#include <kernel/assembly/symbolic_assembler.hpp>
26#include <kernel/assembly/domain_assembler_basic_jobs.hpp>
27#include <kernel/assembly/bilinear_operator_assembler.hpp>
28#include <kernel/assembly/common_operators.hpp>
29#include <kernel/assembly/gpdv_assembler.hpp>
30#include <kernel/assembly/grid_transfer.hpp>
31#include <kernel/assembly/mean_filter_assembler.hpp>
32#include <kernel/assembly/unit_filter_assembler.hpp>
33#include <kernel/global/gate.hpp>
34#include <kernel/global/muxer.hpp>
35#include <kernel/global/vector.hpp>
36#include <kernel/global/matrix.hpp>
37#include <kernel/global/filter.hpp>
38#include <kernel/global/mean_filter.hpp>
39#include <kernel/global/symmetric_lumped_schur_matrix.hpp>
40#include <kernel/global/transfer.hpp>
41
42#include <control/domain/domain_control.hpp>
43#include <control/asm/gate_asm.hpp>
44#include <control/asm/muxer_asm.hpp>
45#include <control/asm/splitter_asm.hpp>
46#include <control/asm/transfer_asm.hpp>
47
48namespace FEAT
49{
50 namespace Control
51 {
52 template
53 <
54 int dim_,
55 typename DataType_ = Real,
56 typename IndexType_ = Index,
57 typename MatrixBlockA_ = LAFEM::SparseMatrixBCSR<DataType_, IndexType_, dim_, dim_>,
58 typename MatrixBlockB_ = LAFEM::SparseMatrixBCSR<DataType_, IndexType_, dim_, 1>,
59 typename MatrixBlockD_ = LAFEM::SparseMatrixBCSR<DataType_, IndexType_, 1, dim_>,
60 typename ScalarMatrix_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_>,
61 typename TransferMatrixV_ = LAFEM::SparseMatrixBWrappedCSR<DataType_, IndexType_, dim_>,
62 typename TransferMatrixP_ = LAFEM::SparseMatrixCSR<DataType_, IndexType_>
63 >
65 {
66 public:
67 // basic types
68 typedef DataType_ DataType;
69 typedef IndexType_ IndexType;
70 static constexpr int dim = dim_;
71
72 // scalar types
73 typedef ScalarMatrix_ LocalScalarMatrix;
74 typedef typename LocalScalarMatrix::VectorTypeL LocalScalarVector;
75
76 // define local blocked matrix type
77 typedef MatrixBlockA_ LocalMatrixBlockA;
78 typedef MatrixBlockB_ LocalMatrixBlockB;
79 typedef MatrixBlockD_ LocalMatrixBlockD;
81
82 // define local vector types
83 typedef typename LocalMatrixBlockB::VectorTypeL LocalVeloVector;
84 typedef typename LocalMatrixBlockD::VectorTypeL LocalPresVector;
86
87 // define local filter types
92
93 // define local transfer matrix types
94 typedef TransferMatrixV_ LocalVeloTransferMatrix;
95 typedef TransferMatrixP_ LocalPresTransferMatrix;
97
98 // define local transfer operators
102
103 // define mirror types
105 typedef ScalarMirror VeloMirror;
106 typedef ScalarMirror PresMirror;
108
109 // define gates
113
114 // define muxers
118
119 // define splitters
123
124 // define global vector types
128
129 // define global filter types
133
134 // define global matrix types
139
140 // define global transfer types
144
145 /* ***************************************************************************************** */
146
149 PresGate gate_pres;
150 SystemGate gate_sys;
151
154 PresMuxer coarse_muxer_pres;
155 SystemMuxer coarse_muxer_sys;
156
159 PresSplitter base_splitter_pres;
160 SystemSplitter base_splitter_sys;
161
164 GlobalVeloVector lumped_matrix_a;
165 GlobalMatrixBlockB matrix_b;
166 GlobalMatrixBlockD matrix_d;
167 GlobalSystemMatrix matrix_sys;
168
171 GlobalPresTransfer transfer_pres;
172 GlobalSystemTransfer transfer_sys;
173
174 // (global) filters
175 GlobalSystemFilter filter_sys;
176 GlobalVeloFilter filter_velo;
177 GlobalPresFilter filter_pres;
178
184 lumped_matrix_a(&gate_velo),
185 matrix_b(&gate_velo, &gate_pres),
186 matrix_d(&gate_pres, &gate_velo),
187 matrix_sys(&gate_sys, &gate_sys),
189 transfer_pres(&coarse_muxer_pres),
190 transfer_sys(&coarse_muxer_sys)
191 {
192 }
193
201 explicit ScalarMixedSystemLevel(const std::deque<String>& neumann_list) :
203 lumped_matrix_a(&gate_velo),
204 matrix_b(&gate_velo, &gate_pres),
205 matrix_d(&gate_pres, &gate_velo),
206 matrix_sys(&gate_sys, &gate_sys),
208 transfer_pres(&coarse_muxer_pres),
209 transfer_sys(&coarse_muxer_sys),
210 filter_velo(neumann_list)
211 {
212 }
213
214 // no copies, no problems
216 ScalarMixedSystemLevel& operator=(const ScalarMixedSystemLevel&) = delete;
217
219 {
220 }
221
223 std::size_t bytes() const
224 {
225 //return (*this->matrix_sys).bytes () + (*this->matrix_s).bytes() + transfer_sys.bytes();
226 return matrix_sys.bytes() + filter_sys.bytes() + transfer_sys.bytes();
227 }
228
229 void compile_system_matrix()
230 {
231 if(lumped_matrix_a.local().size() == Index(0))
232 {
233 lumped_matrix_a.local() = matrix_a.local().create_vector_l();
234 }
235
236 matrix_a.lump_rows(lumped_matrix_a);
237
238 matrix_sys.local().block_a() = matrix_a.local().clone(LAFEM::CloneMode::Shallow);
239 matrix_sys.local().block_b() = matrix_b.local().clone(LAFEM::CloneMode::Shallow);
240 matrix_sys.local().block_d() = matrix_d.local().clone(LAFEM::CloneMode::Shallow);
241 }
242
243 void compile_system_transfer()
244 {
245 transfer_sys.get_mat_prol().template at<0,0>()
247 transfer_sys.get_mat_rest().template at<0,0>()
249 transfer_sys.get_mat_prol().template at<1,1>()
250 = transfer_pres.get_mat_prol().clone(LAFEM::CloneMode::Shallow);
251 transfer_sys.get_mat_rest().template at<1,1>()
252 = transfer_pres.get_mat_rest().clone(LAFEM::CloneMode::Shallow);
253 }
254
255 template<typename D_, typename I_, typename SMA_, typename SMB_, typename SMD_, typename SM_, typename TV_, typename TP_>
256 void convert(const ScalarMixedSystemLevel<dim_, D_, I_, SMA_, SMB_, SMD_, SM_, TV_, TP_> & other)
257 {
258 gate_velo.convert(other.gate_velo);
259 gate_pres.convert(other.gate_pres);
260 gate_sys.convert(other.gate_sys);
261
262 coarse_muxer_velo.convert(other.coarse_muxer_velo);
263 coarse_muxer_pres.convert(other.coarse_muxer_pres);
264 coarse_muxer_sys.convert(other.coarse_muxer_sys);
265
266 base_splitter_velo.convert(other.base_splitter_velo);
267 base_splitter_pres.convert(other.base_splitter_pres);
268 Asm::build_splitter_tuple(this->base_splitter_sys, this->gate_sys.get_freqs(), this->base_splitter_velo, this->base_splitter_pres);
269
270 matrix_a.convert(&gate_velo, &gate_velo, other.matrix_a);
271 matrix_b.convert(&gate_velo, &gate_pres, other.matrix_b);
272 matrix_d.convert(&gate_pres, &gate_velo, other.matrix_d);
273
275 transfer_pres.convert(&coarse_muxer_pres, other.transfer_pres);
276
277 this->compile_system_matrix();
278 this->compile_system_transfer();
279
280 filter_velo.convert(other.filter_velo);
281 filter_pres.convert(other.filter_pres);
282
283 this->compile_system_filter();
284 }
285
286 template<typename DomainLevel_>
287 void assemble_gates(const Domain::VirtualLevel<DomainLevel_>& virt_dom_lvl)
288 {
289 Asm::asm_gate(virt_dom_lvl, virt_dom_lvl->space_velo, this->gate_velo, true);
290 Asm::asm_gate(virt_dom_lvl, virt_dom_lvl->space_pres, this->gate_pres, true);
291 Asm::build_gate_tuple(this->gate_sys, this->gate_velo, this->gate_pres);
292 //this->gate_scalar_velo.convert(this->gate_velo, LocalScalarVector(virt_dom_lvl->space_velo.get_num_dofs()));
293 }
294
295 template<typename DomainLevel_>
296 void assemble_coarse_muxers(const Domain::VirtualLevel<DomainLevel_>& virt_lvl_coarse)
297 {
298 Asm::asm_muxer(virt_lvl_coarse, [](const DomainLevel_& dl){return &dl.space_velo;}, this->coarse_muxer_velo);
299 Asm::asm_muxer(virt_lvl_coarse, [](const DomainLevel_& dl){return &dl.space_pres;}, this->coarse_muxer_pres);
300 Asm::build_muxer_tuple(this->coarse_muxer_sys, this->gate_sys.get_freqs(), this->coarse_muxer_velo, this->coarse_muxer_pres);
301 //this->coarse_muxer_scalar_velo.convert(this->coarse_muxer_velo, this->gate_scalar_velo.get_freqs().clone(LAFEM::CloneMode::Shallow));
302 }
303
304 template<typename DomainLevel_>
305 void assemble_base_splitters(const Domain::VirtualLevel<DomainLevel_>& virt_lvl)
306 {
307 Asm::asm_splitter(virt_lvl, [](const DomainLevel_& dl){return &dl.space_velo;}, this->base_splitter_velo);
308 Asm::asm_splitter(virt_lvl, [](const DomainLevel_& dl){return &dl.space_pres;}, this->base_splitter_pres);
309 Asm::build_splitter_tuple(this->base_splitter_sys, this->gate_sys.get_freqs(), this->base_splitter_velo, this->base_splitter_pres);
310 //this->base_splitter_scalar_velo.convert(this->base_splitter_velo, this->gate_scalar_velo.get_freqs().clone(LAFEM::CloneMode::Shallow));
311 }
312
313 template<typename DomainLevel_>
314 void assemble_transfers(
315 const ScalarMixedSystemLevel& sys_lvl_coarse,
316 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_fine,
317 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_coarse,
318 const String& cubature, bool trunc_v = false, bool trunc_p = false, bool shrink = true)
319 {
320 Asm::asm_transfer_blocked(virt_lvl_fine, virt_lvl_coarse, cubature, trunc_v, shrink,
321 [](const DomainLevel_& dl) {return &dl.space_velo;},
322 this->transfer_velo.local(), this->coarse_muxer_velo, this->gate_velo, sys_lvl_coarse.gate_velo);
323 Asm::asm_transfer_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc_p, shrink,
324 [](const DomainLevel_& dl) {return &dl.space_pres;},
325 this->transfer_pres.local(), this->coarse_muxer_pres, this->gate_pres, sys_lvl_coarse.gate_pres);
326
327 this->transfer_velo.compile();
328 this->transfer_pres.compile();
329 this->compile_system_transfer();
330 }
331
332 template<typename DomainLevel_>
333 void assemble_transfers(
334 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_fine,
335 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_coarse,
336 const String& cubature, bool trunc_v = false, bool trunc_p = false, bool shrink = true)
337 {
338 // if the coarse level is a parent, then we need the coarse system level
339 XASSERT(!virt_lvl_coarse.is_parent());
340
341 Asm::asm_transfer_blocked(virt_lvl_fine, virt_lvl_coarse, cubature, trunc_v, shrink,
342 [](const DomainLevel_& dl) {return &dl.space_velo;},
343 this->transfer_velo.local(), this->coarse_muxer_velo, this->gate_velo, this->gate_velo);
344 Asm::asm_transfer_scalar(virt_lvl_fine, virt_lvl_coarse, cubature, trunc_p, shrink,
345 [](const DomainLevel_& dl) {return &dl.space_pres;},
346 this->transfer_pres.local(), this->coarse_muxer_pres, this->gate_pres, this->gate_pres);
347
348 this->transfer_velo.compile();
349 this->transfer_pres.compile();
350 this->compile_system_transfer();
351 }
352
353 template<typename SpaceVelo_, typename SpacePres_, typename Cubature_>
354 void assemble_grad_div_matrices(const SpaceVelo_& space_velo, const SpacePres_& space_pres, const Cubature_& cubature)
355 {
356 Assembly::GradPresDivVeloAssembler::assemble(this->matrix_b.local(), this->matrix_d.local(),
357 space_velo, space_pres, cubature, DataType(1), DataType(1));
358 }
359
360 template<typename SpaceVelo_>
361 void assemble_velo_struct(const SpaceVelo_& space_velo)
362 {
363 // assemble matrix structure
364 Assembly::SymbolicAssembler::assemble_matrix_std1(this->matrix_a.local(), space_velo);
365 }
366
367 void compile_system_filter()
368 {
369 filter_sys.local().template at<0>() = filter_velo.local().clone(LAFEM::CloneMode::Shallow);
370 filter_sys.local().template at<1>() = filter_pres.local().clone(LAFEM::CloneMode::Shallow);
371 }
372
373 void assemble_global_filters()
374 {
375 // Sync the filter vector in the SlipFilter
376 const VeloGate& my_col_gate(this->gate_velo);
377
378 // For all slip filters...
379 for(auto& it : filter_sys.local().template at<0>())
380 {
381
382 // Get the filter vector
383 auto& slip_filter_vector = it.second.get_filter_vector();
384
385 // If the filter is not empty (meaning the MeshPart is on our patch):
386 if(slip_filter_vector.used_elements() > 0)
387 {
388 // Temporary DenseVector for syncing
389 LocalVeloVector tmp(slip_filter_vector.size(), DataType_(0));
390
391 auto* tmp_elements = tmp.template elements<LAFEM::Perspective::native>();
392 auto* sfv_elements = slip_filter_vector.template elements<LAFEM::Perspective::native>();
393
394 // Copy sparse filter vector contents to DenseVector
395 for(Index isparse(0); isparse < slip_filter_vector.used_elements(); ++isparse)
396 {
397 Index idense(slip_filter_vector.indices()[isparse]);
398 tmp_elements[idense] = sfv_elements[isparse];
399 }
400
401 // Synchronize the temporary DenseVector
402 my_col_gate.sync_0(tmp);
403
404 // Copy sparse filter vector contents to DenseVector
405 for(Index isparse(0); isparse < slip_filter_vector.used_elements(); ++isparse)
406 {
407 Index idense(slip_filter_vector.indices()[isparse]);
408 tmp_elements[idense].normalize();
409 sfv_elements[isparse] = tmp_elements[idense];
410
411 }
412 }
413 // This happens if the non-empty MeshPart belonging to this filter is not present on this patch
414 else
415 {
416 // Temporary DenseVector for syncing
417 LocalVeloVector tmp(slip_filter_vector.size(), DataType_(0));
418 my_col_gate.sync_0(tmp);
419 }
420 }
421 }
422 }; // class ScalarMixedSystemLevel<...>
423 } // namespace Control
424} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
FEAT Kernel base header.
static void assemble(LAFEM::SparseMatrixBCSR< DataType_, IndexType_, dim_, 1 > &matrix_b, LAFEM::SparseMatrixBCSR< DataType_, IndexType_, 1, dim_ > &matrix_d, const SpaceVelo_ &space_velo, const SpacePres_ &space_pres, const String &cubature_name, const DataType_ scale_b=-DataType_(1), const DataType_ scale_d=-DataType_(1))
Assembles the B and D matrices.
static void assemble_matrix_std1(MatrixType_ &matrix, const Space_ &space)
Assembles a standard matrix structure from a single space.
VeloSplitter base_splitter_velo
our base-mesh multiplexer
GlobalVeloTransfer transfer_velo
our global transfer operator
ScalarMixedSystemLevel()
Empty standard constructor.
ScalarMixedSystemLevel(const std::deque< String > &neumann_list)
Constructor for using essential boundary conditions.
VeloMuxer coarse_muxer_velo
our coarse-level system muxer
GlobalMatrixBlockA matrix_a
our global system matrix
std::size_t bytes() const
Returns the total amount of bytes allocated.
Global Filter wrapper class template.
Definition: filter.hpp:21
std::size_t bytes() const
Returns the total amount of bytes allocated.
Definition: filter.hpp:77
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
const LocalVector_ & get_freqs() const
Returns a const reference to the frequencies vector.
Definition: gate.hpp:179
Global Matrix wrapper class template.
Definition: matrix.hpp:40
std::size_t bytes() const
Returns the total amount of bytes allocated.
Definition: matrix.hpp:265
void lump_rows(VectorTypeL &lump, bool sync=true) const
Computes the lumped rows of the matrix as a vector.
Definition: matrix.hpp:556
LocalMatrix_ & local()
Returns a reference to the internal local LAFEM matrix object.
Definition: matrix.hpp:126
Global multiplexer/demultiplexer implementation.
Definition: muxer.hpp:68
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
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
Transfer clone(LAFEM::CloneMode clone_mode=LAFEM::CloneMode::Weak) const
Creates a clone of this object.
Definition: transfer.hpp:125
std::size_t bytes() const
Definition: transfer.hpp:143
LocalTransfer_ & local()
Definition: transfer.hpp:131
Global vector wrapper class template.
Definition: vector.hpp:68
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Definition: vector.hpp:121
Sequence of filters of the same type.
FilterSequence clone(CloneMode clone_mode=CloneMode::Deep) const
Creates a clone of itself.
None Filter class template.
Definition: none_filter.hpp:29
NoneFilter clone(CloneMode=CloneMode::Deep) const
Creates a (empty) clone of itself.
Definition: none_filter.hpp:51
Saddle-Point matrix meta class template.
MatrixTypeA & block_a()
Returns the sub-matrix block A.
MatrixTypeB & block_b()
Returns the sub-matrix block B.
MatrixTypeD & block_d()
Returns the sub-matrix block D.
Slip Filter class template.
Definition: slip_filter.hpp:67
Grid-Transfer operator class template.
Definition: transfer.hpp:27
Tuple-Diag-Matrix meta class template.
TupleVector meta-filter class template.
TupleVector meta-mirror class template.
Variadic TupleVector class template.
Handles vector prolongation, restriction and serialization.
@ other
generic/other permutation strategy
FEAT namespace.
Definition: adjactor.hpp:12
double Real
Real data type.
std::uint64_t Index
Index data type.