Rheolef  7.1
an efficient C++ finite element environment
space_numbering.cc
Go to the documentation of this file.
1 #include "rheolef/space_numbering.h"
22 #include "rheolef/geo.h"
23 #include "rheolef/rheostream.h"
24 namespace rheolef { namespace space_numbering {
25 
26 template <class T>
29  const basis_basic<T>& b,
30  const geo_size& gs,
32 {
33  size_type ndof = 0;
35  ndof += gs.ownership_by_variant [variant].size() * b.ndof_on_subgeo (map_dim, variant);
36  }
37  return ndof;
38 }
39 template <class T>
42  const basis_basic<T>& b,
43  const geo_size& gs,
45 {
46  size_type dis_ndof = 0;
48  dis_ndof += gs.ownership_by_variant [variant].dis_size() * b.ndof_on_subgeo (map_dim, variant);
49  }
50  return dis_ndof;
51 }
52 template <class T>
55  const basis_basic<T>& b,
56  const geo_size& gs,
58 {
59  size_type nnod = 0;
61  nnod += gs.ownership_by_variant [variant].size() * b.nnod_on_subgeo (map_dim, variant);
62  }
63  return nnod;
64 }
65 template <class T>
68  const basis_basic<T>& b,
69  const geo_size& gs,
71 {
72  size_type dis_nnod = 0;
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 // --------------------------------------------------------------------------
81 template <class Callback>
82 static
83 void
84 dis_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
153 template<class T>
154 struct 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 };
164 template<class T>
165 struct 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 };
175 template <class T>
176 void
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 }
185 template <class T>
186 void
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 }
195 template <class T>
196 void
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 }
209 template <class T>
210 void
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 // --------------------------------------------------------------------------
232 template <class T>
233 void
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,
246  variant_last = reference_element::last_variant_by_dimension(map_d);
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,
259  variant_last = reference_element::last_variant_by_dimension(map_d);
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 }
273 template <class T>
274 void
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) \
293 template size_type ndof ( \
294  const basis_basic<T>& b, \
295  const geo_size& gs, \
296  size_type map_dim); \
297 template size_type nnod ( \
298  const basis_basic<T>& b, \
299  const geo_size& gs, \
300  size_type map_dim); \
301 template size_type dis_ndof ( \
302  const basis_basic<T>& b, \
303  const geo_size& gs, \
304  size_type map_dim); \
305 template size_type dis_nnod ( \
306  const basis_basic<T>& b, \
307  const geo_size& gs, \
308  size_type map_dim); \
309 template 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); \
314 template 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); \
319 template 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); \
324 template 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) \
334 template 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); \
341 template 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:425
see the Float page for the full documentation
see the disarray page for the full documentation
Definition: disarray.h:459
see the distributor page for the full documentation
Definition: distributor.h:62
size_type find_owner(size_type dis_i) const
find iproc associated to a global index dis_i: CPU=log(nproc)
Definition: distributor.cc:106
size_type dis_size() const
global and local sizes
Definition: distributor.h:207
size_type size(size_type iproc) const
Definition: distributor.h:163
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
Definition: distributor.h:151
static const size_type decide
Definition: distributor.h:76
const communicator_type & comm() const
Definition: distributor.h:145
distributed mesh with rerefence counting
Definition: geo.h:1367
size_type map_dimension() const
Definition: geo.h:1410
const std::array< disarray< size_type, distributed >, reference_element::max_variant > & get_igev2ios_dis_igev() const
Definition: geo.h:1570
const geo_size & sizes() const
Definition: geo.h:1424
see the geo_element page for the full documentation
Definition: geo_element.h:102
reference_element::size_type size_type
Definition: geo_element.h:125
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)
Definition: geo_element.cc:320
variant_type variant() const
Definition: geo_element.h:161
size_type subgeo_dis_index(size_type subgeo_dim, size_type i) const
Definition: geo_element.h:214
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
size_t size_type
Definition: basis_get.cc:76
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)
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)
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)
geo_element::size_type size_type
This file is part of Rheolef.
_RHEOLEF_instanciate(Float, sequential) _RHEOLEF_instanciate(Float
#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