FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
splitter_asm.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/vector_mirror.hpp>
12#include <kernel/global/splitter.hpp>
13#include <kernel/assembly/mirror_assembler.hpp>
14
15#include <control/domain/domain_control.hpp>
16#include <control/asm/muxer_asm.hpp>
17
18namespace FEAT
19{
20 namespace Control
21 {
22 namespace Asm
23 {
45 template<typename DomainLevel_, typename SpaceLambda_, typename BaseSplitter_>
46 void asm_splitter(const Domain::VirtualLevel<DomainLevel_>& virt_lvl,
47 SpaceLambda_&& space_lambda, BaseSplitter_& base_splitter)
48 {
49 typedef typename BaseSplitter_::LocalVectorType VectorType;
50 typedef typename BaseSplitter_::MirrorType MirrorType;
51
52 // get the layer
53 const auto& layer = virt_lvl.layer();
54
55 // nothing to assemble?
56 if(layer.comm().size() <= 1)
57 return;
58
59 // ensure that this virtual level has a base-mesh
60 XASSERTM(virt_lvl.has_base(), "cannot assemble base splitter because level has no base");
61
62 // is this the root process?
63 if(layer.comm().rank() == 0)
64 {
65 const DomainLevel_& level_b = virt_lvl.level_b();
66
67 // set parent vector template
68 base_splitter.set_base_vector_template(VectorType(space_lambda(level_b)->get_num_dofs()));
69
70 // assemble patch mirrors on root process
71 for(int i(0); i < layer.comm().size(); ++i)
72 {
73 const auto* patch = level_b.find_patch_part(i);
74 XASSERT(patch != nullptr);
75 MirrorType patch_mirror;
76 Assembly::MirrorAssembler::assemble_mirror(patch_mirror, *space_lambda(level_b), *patch);
77 base_splitter.push_patch(std::move(patch_mirror));
78 }
79 }
80
81 // assemble base splitter child
82 const DomainLevel_& level = virt_lvl.level();
83
84 Index num_dofs = space_lambda(level)->get_num_dofs();
85
86 // set parent and sibling comms
87 base_splitter.set_root(layer.comm_ptr(), 0, MirrorType::make_identity(num_dofs));
88
89 // compile base splitter
90 base_splitter.compile(VectorType(num_dofs));
91 }
92
116 template<typename SysSplitter_, typename Splitter0_, typename Splitter1_>
117 void build_splitter_tuple(SysSplitter_& splitter_sys, const typename SysSplitter_::LocalVectorType& tmpl_vec, const Splitter0_& splitter_0, const Splitter1_& splitter_1)
118 {
119 // build the internal tuple muxer
120 typename SysSplitter_::MuxerType sys_muxer;
121 build_muxer_tuple(sys_muxer, tmpl_vec, splitter_0.get_muxer(), splitter_1.get_muxer());
122
123 // build the internal base vector template
124 typename SysSplitter_::LocalVectorType base_vector_tmpl;
125 base_vector_tmpl.template at<0>().clone(splitter_0.get_base_vector_template(), LAFEM::CloneMode::Shallow);
126 base_vector_tmpl.template at<1>().clone(splitter_1.get_base_vector_template(), LAFEM::CloneMode::Shallow);
127
128 // create the splitter
129 splitter_sys = SysSplitter_(std::move(sys_muxer), std::move(base_vector_tmpl));
130 }
131
158 template<typename SysSplitter_, typename Splitter0_, typename Splitter1_, typename Splitter2_>
159 void build_splitter_tuple(SysSplitter_& splitter_sys, const typename SysSplitter_::LocalVectorType& tmpl_vec,
160 const Splitter0_& splitter_0, const Splitter1_& splitter_1, const Splitter2_& splitter_2)
161 {
162 // build the internal tuple muxer
163 typename SysSplitter_::MuxerType sys_muxer;
164 build_muxer_tuple(sys_muxer, tmpl_vec, splitter_0.get_muxer(), splitter_1.get_muxer());
165
166 // build the internal base vector template
167 typename SysSplitter_::LocalVectorType base_vector_tmpl;
168 base_vector_tmpl.template at<0>().clone(splitter_0.get_base_vector_template(), LAFEM::CloneMode::Shallow);
169 base_vector_tmpl.template at<1>().clone(splitter_1.get_base_vector_template(), LAFEM::CloneMode::Shallow);
170 base_vector_tmpl.template at<2>().clone(splitter_2.get_base_vector_template(), LAFEM::CloneMode::Shallow);
171
172 // create the splitter
173 splitter_sys = SysSplitter_(std::move(sys_muxer), std::move(base_vector_tmpl));
174 }
175 } // namespace Asm
176 } // namespace Control
177} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
static void assemble_mirror(LAFEM::VectorMirror< DataType_, IndexType_ > &vec_mirror, const Space_ &space, const MeshPart_ &mesh_part)
Assembles a VectorMirror from a space and a mesh-part.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.