FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
muxer_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/gate.hpp>
13#include <kernel/global/muxer.hpp>
14#include <kernel/assembly/mirror_assembler.hpp>
15
16#include <control/domain/domain_control.hpp>
17
18namespace FEAT
19{
20 namespace Control
21 {
22 namespace Asm
23 {
40 template<typename DomainLevel_, typename SpaceLambda_, typename Muxer_>
41 void asm_muxer(const Domain::VirtualLevel<DomainLevel_>& virt_lvl_c, SpaceLambda_&& space_lambda, Muxer_& muxer)
42 {
43 typedef typename Muxer_::LocalVectorType VectorType;
44 typedef typename Muxer_::MirrorType MirrorType;
45
46 // assemble muxer parent
47 if(virt_lvl_c.is_parent())
48 {
49 XASSERT(virt_lvl_c.is_child());
50
51 const auto& layer_c = virt_lvl_c.layer_c();
52 const DomainLevel_& level_p = virt_lvl_c.level_p();
53
54 // loop over all children
55 for(Index i(0); i < layer_c.child_count(); ++i)
56 {
57 const auto* child = level_p.find_patch_part(int(i));
58 XASSERT(child != nullptr);
59 MirrorType child_mirror;
60 Assembly::MirrorAssembler::assemble_mirror(child_mirror, *space_lambda(level_p), *child);
61 muxer.push_child(std::move(child_mirror));
62 }
63 }
64
65 // assemble muxer child
66 if(virt_lvl_c.is_child())
67 {
68 const auto& layer_c = virt_lvl_c.layer_c();
69 const DomainLevel_& level_c = virt_lvl_c.level_c();
70
71 Index num_dofs = space_lambda(level_c)->get_num_dofs();
72
73 // set parent and sibling comms
74 muxer.set_parent(
75 layer_c.sibling_comm_ptr(),
76 layer_c.get_parent_rank(),
77 MirrorType::make_identity(num_dofs)
78 );
79
80 // compile muxer
81 muxer.compile(VectorType(num_dofs));
82 }
83 }
84
108 template<typename SysMuxer_, typename Muxer0_, typename Muxer1_>
109 void build_muxer_tuple(SysMuxer_& muxer_sys, const typename SysMuxer_::LocalVectorType& tmpl_vec,
110 const Muxer0_& muxer_0, const Muxer1_& muxer_1)
111 {
112 typedef typename SysMuxer_::MirrorType SystemMirrorType;
113
114 // the sibling communicator must be equal for all muxers
115 XASSERTM(muxer_0.get_sibling_comm() == muxer_1.get_sibling_comm(), "muxers have incompatible sibling communicators");
116
117 // do we actually have a parent?
118 if(muxer_0.get_sibling_comm() != nullptr)
119 {
120 // build the parent mirror
121 SystemMirrorType parent_mirror;
122 parent_mirror.template at<0>().clone(muxer_0.get_parent_mirror(), LAFEM::CloneMode::Shallow);
123 parent_mirror.template at<1>().clone(muxer_1.get_parent_mirror(), LAFEM::CloneMode::Shallow);
124
125 // set the parent
126 muxer_sys.set_parent(muxer_0.get_sibling_comm(), muxer_0.get_parent_rank(), std::move(parent_mirror));
127 }
128
129 // get the child mirrors
130 const auto& child_mirrors_0 = muxer_0.get_child_mirrors();
131 const auto& child_mirrors_1 = muxer_1.get_child_mirrors();
132
133 // all child mirror vectors must have the same size
134 XASSERT(child_mirrors_0.size() == child_mirrors_1.size());
135
136 // loop over all child ranks
137 for(std::size_t i(0); i < child_mirrors_0.size(); ++i)
138 {
139 // build the child mirror
140 SystemMirrorType child_mirror;
141 child_mirror.template at<0>().clone(child_mirrors_0[i], LAFEM::CloneMode::Shallow);
142 child_mirror.template at<1>().clone(child_mirrors_1[i], LAFEM::CloneMode::Shallow);
143
144 // child mirror cannot be empty
145 XASSERTM(!child_mirror.empty(), "invalid empty mirror");
146 muxer_sys.push_child(std::move(child_mirror));
147 }
148
149 // compile
150 muxer_sys.compile(tmpl_vec);
151 }
152
179 template<typename SysMuxer_, typename Muxer0_, typename Muxer1_, typename Muxer2_>
180 void build_muxer_tuple(SysMuxer_& muxer_sys, const typename SysMuxer_::LocalVectorType& tmpl_vec,
181 const Muxer0_& muxer_0, const Muxer1_& muxer_1, const Muxer2_& muxer_2)
182 {
183 typedef typename SysMuxer_::MirrorType SystemMirrorType;
184
185 // the sibling communicator must be equal for all muxers
186 XASSERTM(muxer_0.get_sibling_comm() == muxer_1.get_sibling_comm(), "muxers have incompatible sibling communicators");
187 XASSERTM(muxer_0.get_sibling_comm() == muxer_2.get_sibling_comm(), "muxers have incompatible sibling communicators");
188
189 // do we actually have a parent?
190 if(muxer_0.get_sibling_comm() != nullptr)
191 {
192 // build the parent mirror
193 SystemMirrorType parent_mirror;
194 parent_mirror.template at<0>().clone(muxer_0.get_parent_mirror(), LAFEM::CloneMode::Shallow);
195 parent_mirror.template at<1>().clone(muxer_1.get_parent_mirror(), LAFEM::CloneMode::Shallow);
196 parent_mirror.template at<2>().clone(muxer_2.get_parent_mirror(), LAFEM::CloneMode::Shallow);
197
198 // set the parent
199 muxer_sys.set_parent(muxer_0.get_sibling_comm(), muxer_0.get_parent_rank(), std::move(parent_mirror));
200 }
201
202 // get the child mirrors
203 const auto& child_mirrors_0 = muxer_0.get_child_mirrors();
204 const auto& child_mirrors_1 = muxer_1.get_child_mirrors();
205 const auto& child_mirrors_2 = muxer_2.get_child_mirrors();
206
207 // all child mirror vectors must have the same size
208 XASSERT(child_mirrors_0.size() == child_mirrors_1.size());
209 XASSERT(child_mirrors_0.size() == child_mirrors_2.size());
210
211 // loop over all child ranks
212 for(std::size_t i(0); i < child_mirrors_0.size(); ++i)
213 {
214 // build the child mirror
215 SystemMirrorType child_mirror;
216 child_mirror.template at<0>().clone(child_mirrors_0[i], LAFEM::CloneMode::Shallow);
217 child_mirror.template at<1>().clone(child_mirrors_1[i], LAFEM::CloneMode::Shallow);
218 child_mirror.template at<2>().clone(child_mirrors_2[i], LAFEM::CloneMode::Shallow);
219
220 // child mirror cannot be empty
221 XASSERTM(!child_mirror.empty(), "invalid empty mirror");
222 muxer_sys.push_child(std::move(child_mirror));
223 }
224
225 // compile
226 muxer_sys.compile(tmpl_vec);
227 }
228 } // namespace Asm
229 } // namespace Control
230} // 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.
@ child
indicates that the level is a child level
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.