Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
space_numbering.cc
Go to the documentation of this file.
1
21#include "rheolef/space_numbering.h"
22#include "rheolef/geo.h"
23#include "rheolef/rheostream.h"
24namespace rheolef { namespace space_numbering {
25
26template <class T>
29 const basis_basic<T>& b,
30 const geo_size& gs,
31 size_type map_dim)
32{
33 size_type ndof = 0;
34 for (size_type variant = 0; variant < reference_element::max_variant; variant++) {
35 ndof += gs.ownership_by_variant [variant].size() * b.ndof_on_subgeo (map_dim, variant);
36 }
37 return ndof;
38}
39template <class T>
42 const basis_basic<T>& b,
43 const geo_size& gs,
44 size_type map_dim)
45{
47 for (size_type variant = 0; variant < reference_element::max_variant; variant++) {
48 dis_ndof += gs.ownership_by_variant [variant].dis_size() * b.ndof_on_subgeo (map_dim, variant);
49 }
50 return dis_ndof;
51}
52template <class T>
55 const basis_basic<T>& b,
56 const geo_size& gs,
57 size_type map_dim)
58{
59 size_type nnod = 0;
60 for (size_type variant = 0; variant < reference_element::max_variant; variant++) {
61 nnod += gs.ownership_by_variant [variant].size() * b.nnod_on_subgeo (map_dim, variant);
62 }
63 return nnod;
64}
65template <class T>
68 const basis_basic<T>& b,
69 const geo_size& gs,
70 size_type map_dim)
71{
73 for (size_type variant = 0; variant < reference_element::max_variant; variant++) {
74 dis_nnod += gs.ownership_by_variant [variant].dis_size() * b.nnod_on_subgeo (map_dim, variant);
75 }
76 return dis_nnod;
77}
78// --------------------------------------------------------------------------
79// dis_inod/dis_idof shared internal function
80// --------------------------------------------------------------------------
81template <class Callback>
82static
83void
84dis_ixxx (
85 const Callback& nxxx_on_subgeo,
86 const geo_size& gs,
87 const geo_element& K,
88 typename std::vector<size_t>::iterator dis_ixxx_tab)
89{
90 typedef size_t size_type;
91 reference_element hat_K = K;
92 size_type K_map_dim = hat_K.dimension();
93 size_type n_comp = nxxx_on_subgeo.n_component();
94 size_type first_loc_ixxx = 0;
95 for (size_type subgeo_dim = 0; subgeo_dim <= K_map_dim; ++subgeo_dim) {
96 for (size_type subgeo_variant = reference_element::first_variant_by_dimension (subgeo_dim);
97 subgeo_variant < reference_element:: last_variant_by_dimension (subgeo_dim); ++subgeo_variant) {
98 if (subgeo_dim == K_map_dim && subgeo_variant != hat_K.variant()) continue;
99 reference_element hat_S (subgeo_variant);
100 size_type loc_ngev = hat_K.n_subgeo_by_variant (hat_S.variant());
101 if (loc_ngev == 0) continue;
102 size_type loc_nxxx_on_subgeo = nxxx_on_subgeo (hat_S.variant());
103 size_type loc_comp_nxxx_on_subgeo = loc_nxxx_on_subgeo / n_comp;
104 // => reduce the basis interface
105 if (loc_nxxx_on_subgeo == 0) continue;
106 // loop on all subgeos S like hat_S and that belongs to K
107 for (size_type loc_ige = 0, loc_nge = hat_K.n_subgeo (hat_S.dimension()); loc_ige < loc_nge; ++ loc_ige) {
108 reference_element hat_S2 = hat_K.subgeo (hat_S.dimension(), loc_ige);
109 if (hat_S2.variant() != hat_S.variant()) continue;
110 // 0) compute loc_igev
111 size_type loc_igev = hat_K.local_subgeo_index2index_by_variant (hat_S.variant(), loc_ige);
112 // 1) compute dis_igev
113 size_type dis_ige = K.subgeo_dis_index (hat_S.dimension(), loc_ige);
114 if (hat_S.dimension() == 0) { dis_ige = gs.dis_inod2dis_iv (dis_ige); }
115 size_type dis_igev = gs.dis_ige2dis_igev_by_variant (hat_S.variant(), dis_ige);
116 // 2) compute dis_ixxx_loc_start
117 size_type dis_ixxx_loc_start = 0;
118 size_type iproc = gs.ownership_by_variant [hat_S.variant()].find_owner (dis_igev);
119 for (size_type prev_subgeo_variant = 0;
120 prev_subgeo_variant < hat_S.variant();
121 prev_subgeo_variant++) {
122 dis_ixxx_loc_start
123 += gs.ownership_by_variant [prev_subgeo_variant]. last_index(iproc)
124 * nxxx_on_subgeo (prev_subgeo_variant);
125 }
126 dis_ixxx_loc_start += dis_igev*nxxx_on_subgeo (hat_S.variant());
127 for (size_type next_subgeo_variant = hat_S.variant()+1;
128 next_subgeo_variant < reference_element::max_variant;
129 next_subgeo_variant++) {
130 dis_ixxx_loc_start
131 += gs.ownership_by_variant [next_subgeo_variant].first_index(iproc)
132 * nxxx_on_subgeo (next_subgeo_variant);
133 }
134 // 3) set all ixxxs
135 size_type loc_ixxx_loc_start = first_loc_ixxx + loc_igev*loc_nxxx_on_subgeo;
136 for (size_type loc_comp_ixxx_on_subgeo = 0; loc_comp_ixxx_on_subgeo < loc_comp_nxxx_on_subgeo; ++loc_comp_ixxx_on_subgeo) {
137 size_type loc_comp_ixxx_on_subgeo_fixed = geo_element::fix_indirect (K, hat_S.variant(), loc_ige, loc_comp_ixxx_on_subgeo, nxxx_on_subgeo.degree());
138 for (size_type i_comp = 0; i_comp < n_comp; ++i_comp) {
139 size_type loc_ixxx = loc_ixxx_loc_start + loc_comp_ixxx_on_subgeo *n_comp + i_comp;
140 dis_ixxx_tab [loc_ixxx] = dis_ixxx_loc_start + loc_comp_ixxx_on_subgeo_fixed*n_comp + i_comp;
141 }
142 }
143 }
144 first_loc_ixxx += loc_ngev*loc_nxxx_on_subgeo;
145 }
146 }
147}
148// --------------------------------------------------------------------------
149// dis_inod/dis_idof call-back
150// --------------------------------------------------------------------------
151// codes for these functions are very similar
152// thus create a call-back that allows one to share one main code between them
153template<class T>
154struct nnod_callback {
155 nnod_callback (const basis_basic<T>& b, size_t map_d)
156 : _b(b), _map_d(map_d) {}
157 size_t operator() (size_t variant) const {
158 return _b.nnod_on_subgeo (_map_d, variant); }
159 size_t n_component() const { return 1; }
160 size_t degree() const { return _b.degree(); }
161 basis_basic<T> _b;
162 size_t _map_d;
163};
164template<class T>
165struct ndof_callback {
166 ndof_callback (const basis_basic<T>& b, size_t map_d)
167 : _b(b), _map_d(map_d) {}
168 size_t operator() (size_t variant) const {
169 return _b.ndof_on_subgeo (_map_d, variant); }
170 size_t n_component() const { return _b.size(); }
171 size_t degree() const { return _b.degree(); }
172 basis_basic<T> _b;
173 size_t _map_d;
174};
175template <class T>
176void
178 const basis_basic<T>& b,
179 const geo_size& gs,
180 const geo_element& K,
181 typename std::vector<size_type>::iterator dis_inod_tab)
182{
183 dis_ixxx (nnod_callback<T> (b, gs.map_dimension()), gs, K, dis_inod_tab);
184}
185template <class T>
186void
188 const basis_basic<T>& b,
189 const geo_size& gs,
190 const geo_element& K,
191 typename std::vector<size_type>::iterator dis_idof_tab)
192{
193 dis_ixxx (ndof_callback<T> (b, gs.map_dimension()), gs, K, dis_idof_tab);
194}
195template <class T>
196void
198 const basis_basic<T>& b,
199 const geo_size& gs,
200 const geo_element& K,
201 std::vector<size_type>& dis_inod_tab)
202{
203 dis_inod_tab.resize (b.nnod (K.variant()));
204#ifdef _RHEOLEF_PARANO
205 std::fill (dis_inod_tab.begin(), dis_inod_tab.end(), std::numeric_limits<size_type>::max());
206#endif // _RHEOLEF_PARANO
207 dis_inod (b, gs, K, dis_inod_tab.begin());
208}
209template <class T>
210void
212 const basis_basic<T>& b,
213 const geo_size& gs,
214 const geo_element& K,
215 std::vector<size_type>& dis_idof_tab)
216{
217 dis_idof_tab.resize (b.ndof (K.variant()));
218#ifdef _RHEOLEF_PARANO
219 std::fill (dis_idof_tab.begin(), dis_idof_tab.end(), std::numeric_limits<size_type>::max());
220#endif // _RHEOLEF_PARANO
221 dis_idof (b, gs, K, dis_idof_tab.begin());
222}
223#ifdef _RHEOLEF_HAVE_MPI
224// -------------------------------------------------------------
225// permut to/from ios dof numbering, for distributed environment
226// --------------------------------------------------------------------------
227// set permutation for idofs: ios_idof2dis_idof & idof2ios_dis_idof
228// and redistribute ios_dof[] into _dof[]
229// applied for initialiing distributed mesh:
230// posibly curved with Pk piola basis.
231// --------------------------------------------------------------------------
232template <class T>
233void
235 const basis_basic<T>& b,
236 size_t map_d,
237 const geo_size& gs,
239 igev2ios_dis_igev,
240 disarray<size_t,distributed>& idof2ios_dis_idof)
241{
243 // 1) count & resize
244 size_type ndof = 0;
245 for (size_type variant = 0,
247 variant < variant_last;
248 variant++) {
249 ndof += gs.ownership_by_variant [variant].size() * b.ndof_on_subgeo (map_d, variant);
250 }
251 communicator comm = gs.ownership_by_variant[0].comm();
252 distributor dof_ownership (distributor::decide, comm, ndof);
253 idof2ios_dis_idof.resize (dof_ownership);
254 // 2) set idof2ios_dis_idof[]
255 size_type first_dis_idof= dof_ownership.first_index();
256 size_type idof = 0;
257 size_type first_ios_dis_v = 0;
258 for (size_type variant = 0,
260 variant < variant_last;
261 variant++) {
262 size_type loc_ndof = b.ndof_on_subgeo (map_d, variant);
263 for (size_type igev = 0, ngev = gs.ownership_by_variant [variant].size(); igev < ngev; igev++) {
264 size_type ios_dis_igev = igev2ios_dis_igev [variant] [igev];
265 for (size_type loc_idof = 0; loc_idof < loc_ndof; loc_idof++, idof++) {
266 size_type ios_dis_idof = first_ios_dis_v + ios_dis_igev*loc_ndof + loc_idof;
267 idof2ios_dis_idof [idof] = ios_dis_idof;
268 }
269 }
270 first_ios_dis_v += gs.ownership_by_variant [variant].dis_size() * loc_ndof;
271 }
272}
273template <class T>
274void
276 const basis_basic<T>& b,
277 const geo_basic<T,distributed>& omega,
278 disarray<size_type,distributed>& idof2ios_dis_idof,
279 disarray<size_type,distributed>& ios_idof2dis_idof)
280{
281 generic_set_ios_permutation (b, omega.map_dimension(), omega.sizes(), omega.get_igev2ios_dis_igev(), idof2ios_dis_idof);
282 size_type dis_ndof = idof2ios_dis_idof.ownership().dis_size();
283 distributor ios_dof_ownership (dis_ndof, idof2ios_dis_idof.comm(), distributor::decide);
284 ios_idof2dis_idof.resize (ios_dof_ownership, std::numeric_limits<size_type>::max());
285 idof2ios_dis_idof.reverse_permutation (ios_idof2dis_idof);
286}
287#endif // _RHEOLEF_HAVE_MPI
288
289// ----------------------------------------------------------------------------
290// instanciation in library
291// ----------------------------------------------------------------------------
292#define _RHEOLEF_instanciate(T) \
293template size_type ndof ( \
294 const basis_basic<T>& b, \
295 const geo_size& gs, \
296 size_type map_dim); \
297template size_type nnod ( \
298 const basis_basic<T>& b, \
299 const geo_size& gs, \
300 size_type map_dim); \
301template size_type dis_ndof ( \
302 const basis_basic<T>& b, \
303 const geo_size& gs, \
304 size_type map_dim); \
305template size_type dis_nnod ( \
306 const basis_basic<T>& b, \
307 const geo_size& gs, \
308 size_type map_dim); \
309template void dis_idof ( \
310 const basis_basic<T>& b, \
311 const geo_size& gs, \
312 const geo_element& K, \
313 typename std::vector<size_type>::iterator dis_inod_tab); \
314template void dis_inod ( \
315 const basis_basic<T>& b, \
316 const geo_size& gs, \
317 const geo_element& K, \
318 typename std::vector<size_type>::iterator dis_inod_tab); \
319template void dis_idof ( \
320 const basis_basic<T>& b, \
321 const geo_size& gs, \
322 const geo_element& K, \
323 std::vector<size_type>& dis_inod_tab); \
324template void dis_inod ( \
325 const basis_basic<T>& b, \
326 const geo_size& gs, \
327 const geo_element& K, \
328 std::vector<size_type>& dis_inod_tab); \
329
331
332#ifdef _RHEOLEF_HAVE_MPI
333#define _RHEOLEF_instanciate_distributed(T) \
334template void generic_set_ios_permutation ( \
335 const basis_basic<T>& b, \
336 size_t map_d, \
337 const geo_size& gs, \
338 const std::array<disarray<size_t,distributed>,reference_element::max_variant>& \
339 igev2ios_dis_igev, \
340 disarray<size_t,distributed>& idof2ios_dis_idof); \
341template void set_ios_permutations ( \
342 const basis_basic<T>& b, \
343 const geo_basic<T,distributed>& omega, \
344 disarray<size_type,distributed>& idof2ios_dis_idof, \
345 disarray<size_type,distributed>& ios_idof2dis_idof); \
346
348#endif // _RHEOLEF_HAVE_MPI
349
350}} // namespace rheolef::space_numbering
field::size_type size_type
Definition branch.cc:430
see the Float page for the full documentation
see the disarray page for the full documentation
Definition disarray.h:497
see the distributor page for the full documentation
Definition distributor.h:69
size_type find_owner(size_type dis_i) const
find iproc associated to a global index dis_i: CPU=log(nproc)
size_type dis_size() const
global and local sizes
size_type size(size_type iproc) const
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
static const size_type decide
Definition distributor.h:83
const communicator_type & comm() const
generic mesh with rerefence counting
Definition geo.h:1089
see the geo_element page for the full documentation
reference_element::size_type size_type
static size_type fix_indirect(const geo_element &K, size_type subgeo_variant, size_type loc_ige, size_type loc_comp_idof_on_subgeo, size_type order)
variant_type variant() const
size_type subgeo_dis_index(size_type subgeo_dim, size_type i) const
see the reference_element page for the full documentation
reference_element subgeo(size_type subgeo_dim, size_type loc_isid) const
static const variant_type max_variant
static variant_type last_variant_by_dimension(size_type dim)
size_type local_subgeo_index2index_by_variant(size_type subgeo_variant, size_type i) const
static variant_type first_variant_by_dimension(size_type dim)
size_type n_subgeo_by_variant(size_type subgeo_variant) const
variant_type variant() const
size_type n_subgeo(size_type subgeo_dim) const
#define _RHEOLEF_instanciate(T)
Definition csr_seq.cc:491
size_type n_component(valued_type valued_tag, size_type d, coordinate_type sys_coord)
void generic_set_ios_permutation(const basis_basic< T > &b, size_t map_d, const geo_size &gs, const std::array< disarray< size_t, distributed >, reference_element::max_variant > &igev2ios_dis_igev, disarray< size_t, distributed > &idof2ios_dis_idof)
void dis_idof(const basis_basic< T > &b, const geo_size &gs, const geo_element &K, typename std::vector< size_type >::iterator dis_idof_tab)
void set_ios_permutations(const basis_basic< T > &b, const geo_basic< T, distributed > &omega, disarray< size_type, distributed > &idof2ios_dis_idof, disarray< size_type, distributed > &ios_idof2dis_idof)
size_type nnod(const basis_basic< T > &b, const geo_size &gs, size_type map_dim)
size_type dis_nnod(const basis_basic< T > &b, const geo_size &gs, size_type map_dim)
size_type dis_ndof(const basis_basic< T > &b, const geo_size &gs, size_type map_dim)
size_type ndof(const basis_basic< T > &b, const geo_size &gs, size_type map_dim)
void dis_inod(const basis_basic< T > &b, const geo_size &gs, const geo_element &K, typename std::vector< size_type >::iterator dis_inod_tab)
geo_element::size_type size_type
This file is part of Rheolef.
#define _RHEOLEF_instanciate_distributed(T)
size_type dis_ige2dis_igev_by_variant(size_type variant, size_type dis_ige) const
Definition geo_size.cc:98
distributor ownership_by_variant[reference_element::max_variant]
Definition geo_size.h:64
size_type map_dimension() const
Definition geo_size.h:41
size_type dis_inod2dis_iv(size_type dis_inod) const
Definition geo_size.cc:110