~ubuntu-branches/ubuntu/trusty/rheolef/trusty

« back to all changes in this revision

Viewing changes to skit/plib2/vec_concat.h

  • Committer: Package Import Robot
  • Author(s): Pierre Saramito
  • Date: 2012-04-06 09:12:21 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120406091221-m58me99p1nxqui49
Tags: 6.0-1
* New upstream release 6.0 (major changes):
  - massively distributed and parallel support
  - full FEM characteristic method (Lagrange-Gakerkin method) support
  - enhanced users documentation 
  - source code supports g++-4.7 (closes: #667356)
* debian/control: dependencies for MPI distributed solvers added
* debian/rules: build commands simplified
* debian/librheolef-dev.install: man1/* to man9/* added
* debian/changelog: package description rewritted (closes: #661689)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _RHEOLEF_VEC_CONCAT_H
 
2
#define _RHEOLEF_VEC_CONCAT_H
 
3
///
 
4
/// This file is part of Rheolef.
 
5
///
 
6
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
 
7
///
 
8
/// Rheolef is free software; you can redistribute it and/or modify
 
9
/// it under the terms of the GNU General Public License as published by
 
10
/// the Free Software Foundation; either version 2 of the License, or
 
11
/// (at your option) any later version.
 
12
///
 
13
/// Rheolef is distributed in the hope that it will be useful,
 
14
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
/// GNU General Public License for more details.
 
17
///
 
18
/// You should have received a copy of the GNU General Public License
 
19
/// along with Rheolef; if not, write to the Free Software
 
20
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
///
 
22
/// =========================================================================
 
23
// build vec from initializer lists
 
24
//
 
25
#include "rheolef/vec.h"
 
26
 
 
27
namespace rheolef {
 
28
 
 
29
template <class T, class M>
 
30
struct vec_concat_value {
 
31
// typedef:
 
32
 typedef enum { scalar, vector} variant_type;
 
33
// allocators:
 
34
 vec_concat_value (const T& x)        : s(x), v(),  variant(scalar) {}
 
35
 vec_concat_value (const vec<T,M>& x) : s(),  v(x), variant(vector) {}
 
36
// io/debug:
 
37
 friend std::ostream& operator<< (std::ostream& o, const vec_concat_value<T,M>& x) {
 
38
  if (x.variant == scalar) return o << "s"; else return o << "v";
 
39
 }
 
40
// data:
 
41
public:
 
42
 T            s;
 
43
 vec<T,M>     v;
 
44
 variant_type variant;
 
45
};
 
46
 
 
47
template <class T, class M>
 
48
struct vec_concat {
 
49
// typedef:
 
50
 typedef typename vec<T,M>::size_type   size_type;
 
51
 typedef vec_concat_value<T,M>          value_type;
 
52
 
 
53
// allocators:
 
54
 
 
55
 vec_concat () : _l() {}
 
56
 
 
57
#ifdef TO_CLEAN
 
58
 vec_concat (const std::initializer_list<vec<T,M> >& il) : _l() {
 
59
#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
 
60
    typedef typename std::initializer_list<vec<T,M> >::const_iterator const_iterator;
 
61
#else // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
 
62
    typedef const vec<T,M>* const_iterator;
 
63
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
 
64
    for(const_iterator iter = il.begin(); iter != il.end(); ++iter) {
 
65
        _l.push_back(value_type(*iter));
 
66
    }
 
67
 }
 
68
#endif // TO_CLEAN
 
69
 
 
70
 vec_concat (const std::initializer_list<value_type>& il) : _l() {
 
71
#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
 
72
    typedef typename std::initializer_list<value_type>::const_iterator const_iterator;
 
73
#else // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
 
74
    typedef const value_type* const_iterator;
 
75
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_ITERATOR
 
76
    for(const_iterator iter = il.begin(); iter != il.end(); ++iter) {
 
77
        _l.push_back(*iter);
 
78
    }
 
79
 }
 
80
 friend std::ostream& operator<< (std::ostream& o, const vec_concat<T,M>& x) {
 
81
    std::cout << "{";
 
82
    for(typename std::list<value_type>::const_iterator iter = x._l.begin(); iter != x._l.end(); ++iter) {
 
83
        std::cout << *iter << " ";
 
84
    }
 
85
    return std::cout << "}";
 
86
  }
 
87
  vec<T,M> build_vec() const;
 
88
// data:
 
89
protected:
 
90
 std::list<value_type> _l;
 
91
};
 
92
template <class T, class M>
 
93
vec<T,M>
 
94
vec_concat<T,M>::build_vec() const
 
95
{
 
96
  // ------------------------------------
 
97
  // first pass: compute the vector size
 
98
  // ------------------------------------
 
99
  size_type s_sz = 0;
 
100
  size_type v_sz = 0;
 
101
  size_type v_dis_sz = 0;
 
102
  communicator comm;
 
103
  for(typename std::list<value_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter) {
 
104
    const vec_concat_value<T,M>& x = *iter;
 
105
    if (x.variant == value_type::vector) {
 
106
      comm      = x.v.ownership().comm();
 
107
      v_sz     += x.v.ownership().size();
 
108
      v_dis_sz += x.v.ownership().dis_size();
 
109
    } else {
 
110
      s_sz++;
 
111
    }
 
112
  }
 
113
  v_dis_sz += s_sz;
 
114
  if (comm.rank() == comm.size() - 1) { v_sz += s_sz; }
 
115
  distributor ownership (v_dis_sz, comm, v_sz);
 
116
  // ------------------------
 
117
  // second pass: copy values
 
118
  // ------------------------
 
119
  vec<T,M> u (ownership);
 
120
  size_type my_proc = comm.rank();
 
121
  size_type last_proc = comm.size() - 1;
 
122
  typename vec<T,M>::iterator pu = u.begin();
 
123
  for(typename std::list<value_type>::const_iterator iter = _l.begin(); iter != _l.end(); ++iter) {
 
124
    const vec_concat_value<T,M>& x = *iter;
 
125
    if (x.variant == value_type::vector) {
 
126
      for (typename vec<T,M>::const_iterator pv = x.v.begin(), lastv = x.v.end(); pv != lastv; pv++) {
 
127
        *pu++ = *pv;
 
128
      }
 
129
    } else {
 
130
      if (my_proc == last_proc) {
 
131
        *pu++ = x.s;
 
132
      }
 
133
    }
 
134
  }
 
135
  return u;
 
136
}
 
137
#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
 
138
template <class T, class M>
 
139
inline
 
140
vec<T,M>::vec (const std::initializer_list<vec_concat_value<T,M> >& init_list)
 
141
{
 
142
  vec_concat<T,M> vc (init_list);
 
143
  vec<T,M>::operator= (vc.build_vec());
 
144
}
 
145
template <class T, class M>
 
146
inline
 
147
vec<T,M>&
 
148
vec<T,M>::operator= (const std::initializer_list<vec_concat_value<T,M> >& init_list)
 
149
{
 
150
  vec_concat<T,M> vc (init_list);
 
151
  vec<T,M>::operator= (vc.build_vec());
 
152
  return *this;
 
153
}
 
154
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST
 
155
 
 
156
} // namespace rheolef
 
157
#endif // _RHEOLEF_VEC_CONCAT_H