9#include <kernel/lafem/dense_vector.hpp>
10#include <kernel/lafem/dense_vector_blocked.hpp>
11#include <kernel/lafem/vector_mirror.hpp>
12#include <kernel/global/gate.hpp>
13#include <kernel/global/transfer.hpp>
14#include <kernel/assembly/symbolic_assembler.hpp>
15#include <kernel/assembly/grid_transfer.hpp>
17#include <control/domain/domain_control.hpp>
63 template<
typename DomainLevel_,
typename SpaceLambda_,
typename Transfer_,
typename Muxer_,
typename Gate_>
64 void asm_transfer_scalar(
65 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_f,
66 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_c,
67 const String& cubature,
bool trunc,
bool shrink,
68 SpaceLambda_&& space_lambda, Transfer_& transfer,
const Muxer_& muxer,
const Gate_& gate_f,
const Gate_& gate_c)
70 typedef typename Transfer_::DataType DataType;
71 typedef typename Transfer_::IndexType IndexType;
72 typedef LAFEM::DenseVector<DataType, IndexType> ScalarVectorType;
75 const DomainLevel_& level_f = *virt_lvl_f;
76 const DomainLevel_& level_c = virt_lvl_c.is_child() ? virt_lvl_c.level_c() : *virt_lvl_c;
79 const auto& space_f = *space_lambda(level_f);
80 const auto& space_c = *space_lambda(level_c);
83 auto& loc_prol = transfer.get_mat_prol();
84 auto& loc_rest = transfer.get_mat_rest();
85 auto& loc_trunc = transfer.get_mat_trunc();
92 auto loc_vec_weight_p = loc_prol.create_vector_l();
93 auto loc_vec_weight_t = loc_prol.create_vector_r();
97 loc_vec_weight_p.format();
98 loc_vec_weight_t.format();
102 loc_trunc.transpose(loc_prol);
112 gate_f.sync_0(loc_vec_weight_p);
115 loc_vec_weight_p.component_invert(loc_vec_weight_p);
118 loc_prol.scale_rows(loc_prol, loc_vec_weight_p);
122 loc_prol.shrink(DataType(1E-3) * loc_prol.max_abs_element());
125 loc_rest = loc_prol.transpose();
137 if(!virt_lvl_c.is_child())
141 gate_c.sync_0(loc_vec_weight_t);
143 else if(virt_lvl_c.is_parent())
152 ScalarVectorType loc_tmp(gate_c.get_freqs().size());
155 muxer.join(loc_vec_weight_t, loc_tmp);
158 gate_c.sync_0(loc_tmp);
161 muxer.split(loc_vec_weight_t, loc_tmp);
169 muxer.join_send(loc_vec_weight_t);
173 muxer.split_recv(loc_vec_weight_t);
177 loc_vec_weight_t.component_invert(loc_vec_weight_t);
180 loc_trunc.scale_rows(loc_trunc, loc_vec_weight_t);
184 loc_trunc.shrink(DataType(1E-3) * loc_trunc.max_abs_element());
225 template<
typename DomainLevel_,
typename SpaceLambda_,
typename Transfer_,
typename Muxer_,
typename Gate_>
226 void asm_transfer_blocked(
227 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_f,
228 const Domain::VirtualLevel<DomainLevel_>& virt_lvl_c,
229 const String& cubature,
bool trunc,
bool shrink,
230 SpaceLambda_&& space_lambda, Transfer_& transfer,
const Muxer_& muxer,
const Gate_& gate_f,
const Gate_& gate_c)
232 typedef typename Transfer_::DataType DataType;
233 typedef typename Transfer_::IndexType IndexType;
234 typedef typename Gate_::MirrorType MirrorType;
235 typedef LAFEM::DenseVector<DataType, IndexType> ScalarVectorType;
238 const DomainLevel_& level_f = *virt_lvl_f;
239 const DomainLevel_& level_c = virt_lvl_c.is_child() ? virt_lvl_c.level_c() : *virt_lvl_c;
242 const auto& space_f = *space_lambda(level_f);
243 const auto& space_c = *space_lambda(level_c);
246 auto& loc_prol_wrapped = transfer.get_mat_prol();
247 auto& loc_rest_wrapped = transfer.get_mat_rest();
248 auto& loc_trunc_wrapped = transfer.get_mat_trunc();
251 auto& loc_prol = loc_prol_wrapped.unwrap();
252 auto& loc_rest = loc_rest_wrapped.unwrap();
253 auto& loc_trunc = loc_trunc_wrapped.unwrap();
256 if (loc_prol.empty())
260 auto loc_vec_weight_p = loc_prol.create_vector_l();
261 auto loc_vec_weight_t = loc_prol.create_vector_r();
265 loc_vec_weight_p.format();
266 loc_vec_weight_t.format();
270 loc_trunc.transpose(loc_prol);
280 Global::Gate<ScalarVectorType, MirrorType> scalar_gate;
284 scalar_gate.sync_0(loc_vec_weight_p);
287 loc_vec_weight_p.component_invert(loc_vec_weight_p);
290 loc_prol.scale_rows(loc_prol, loc_vec_weight_p);
294 loc_prol.shrink(DataType(1E-3) * loc_prol.max_abs_element());
297 loc_rest = loc_prol.transpose();
309 if(!virt_lvl_c.is_child())
317 Global::Gate<ScalarVectorType, MirrorType> scalar_gate_c;
318 scalar_gate_c.convert(gate_c, ScalarVectorType(space_c.get_num_dofs()));
321 scalar_gate_c.sync_0(loc_vec_weight_t);
323 else if(virt_lvl_c.is_parent())
336 const Index num_dofs_c = gate_c.get_freqs().size();
339 Global::Gate<ScalarVectorType, MirrorType> scalar_gate_c;
340 scalar_gate_c.convert(gate_c, ScalarVectorType(num_dofs_c));
343 Global::Muxer<ScalarVectorType, MirrorType> scalar_muxer_f;
344 scalar_muxer_f.convert(muxer, ScalarVectorType(space_f.get_num_dofs()));
347 ScalarVectorType loc_tmp(num_dofs_c);
350 scalar_muxer_f.join(loc_vec_weight_t, loc_tmp);
353 scalar_gate_c.sync_0(loc_tmp);
356 scalar_muxer_f.split(loc_vec_weight_t, loc_tmp);
365 Global::Muxer<ScalarVectorType, MirrorType> scalar_muxer_f;
366 scalar_muxer_f.convert(muxer, ScalarVectorType(space_f.get_num_dofs()));
368 scalar_muxer_f.join_send(loc_vec_weight_t);
372 scalar_muxer_f.split_recv(loc_vec_weight_t);
376 loc_vec_weight_t.component_invert(loc_vec_weight_t);
379 loc_trunc.scale_rows(loc_trunc, loc_vec_weight_t);
383 loc_trunc.shrink(DataType(1E-3) * loc_trunc.max_abs_element());
#define XASSERT(expr)
Assertion macro definition.
static void assemble_truncation(Matrix_ &matrix, Vector_ &vector, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Assembles a truncation matrix and its corresponding weight vector.
static void assemble_prolongation(Matrix_ &matrix, Vector_ &vector, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Assembles a prolongation matrix and its corresponding weight vector.
static void assemble_matrix_2lvl(MatrixType_ &matrix, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space)
Assembles a 2-level matrix structure from a fine-coarse-space pair.
std::uint64_t Index
Index data type.