Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fsfunctionallinearcomposite.hpp
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*-
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2013-04-26
7 
8  Copyright (C) 2013 Feel++ Consortium
9 
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Lesser General Public
12  License as published by the Free Software Foundation; either
13  version 2.1 of the License, or (at your option) any later version.
14 
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public
21  License along with this library; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
30 #ifndef __FSFUNCTIONALLINEARCOMPOSITE_H
31 #define __FSFUNCTIONALLINEARCOMPOSITE_H 1
32 
33 #include <feel/feelalg/backend.hpp>
35 #include <feel/feelvf/vf.hpp>
36 
37 namespace Feel
38 {
39 
40 template<class Space>
41 class FsFunctionalLinearComposite : public FsFunctionalLinear<Space>
42 {
43 public:
44 
45  // -- TYPEDEFS --
46  typedef FsFunctionalLinearComposite<Space> this_type;
47  typedef FsFunctionalLinear<Space> super_type;
48  typedef boost::shared_ptr<super_type> super_ptrtype;
49 
50  typedef Space space_type;
51 
52  typedef boost::shared_ptr<space_type> space_ptrtype;
53  typedef typename space_type::element_type element_type;
54 
55  typedef typename space_type::value_type value_type;
56 
57  typedef Backend<value_type> backend_type;
58  typedef boost::shared_ptr<backend_type> backend_ptrtype;
59 
60  typedef typename backend_type::vector_type vector_type;
61  typedef typename backend_type::vector_ptrtype vector_ptrtype;
62 
63  FsFunctionalLinearComposite( space_ptrtype space ) :
64  super_type( space ),
65  M_backend( backend_type::build( BACKEND_PETSC ) )
66  {}
67 
68  FsFunctionalLinearComposite( space_ptrtype space, backend_ptrtype backend ) :
69  super_type( space ),
70  M_backend( backend )
71  {}
72 
73  int size()
74  {
75  int size1 = M_functionals1.size();
76  int size2 = M_functionals2.size();
77  return size1+size2;
78  }
79 
80 
81  //if we have a list of functionals
82  //i.e. \sum_{q=0}^Q Fq(.)
83  void addElement( super_ptrtype const& functional )
84  {
85  int size = M_functionals1.size();
86  M_functionals1.insert( std::make_pair( size , functional ) ) ;
87  }
88 
89  void addElement( int q, super_ptrtype const& functional )
90  {
91  M_functionals1.insert( std::make_pair( q , functional ) ) ;
92  }
93 
94  void addList( std::vector< super_ptrtype > const& vec )
95  {
96  int q_max=vec.size();
97  for(int q=0; q<q_max; q++)
98  this->addElement( q , vec[q] );
99  }
100 
101 
102  //if we have a list of list of functionals
103  //i.e. \sum_{q=0}^Q \sum_{m=0}^M F_{qm}(.)
104  void addElement( boost::tuple<int,int> const& qm , super_ptrtype const& functional )
105  {
106  M_functionals2.insert( std::make_pair( qm , functional ) );
107  }
108 
109  void addList( std::vector< std::vector< super_ptrtype > > const& vec )
110  {
111  int q_max = vec.size();
112  for(int q=0; q<q_max; q++)
113  {
114  int m_max = vec[q].size();
115  for(int m=0; m<m_max; m++)
116  {
117  auto tuple = boost::make_tuple( q , m );
118  this->addElement( tuple , vec[q][m] );
119  }
120  }
121  }
122 
123 
124  void setScalars( std::vector<double> scalars )
125  {
126  M_scalars1 = scalars;
127  }
128 
129  void setScalars( std::vector< std::vector< double > > scalars )
130  {
131  M_scalars2 = scalars;
132  }
133 
134  this_type& operator=( this_type const& m )
135  {
136  M_backend = m.M_backend;
137  M_functionals1 = m.M_functionals1;
138  M_functionals1 = m.M_functionals2;
139  M_scalars1 = m.M_scalars1;
140  M_scalars2 = m.M_scalars2;
141  return *this;
142  }
143 
144 
145  void sumAllVectors( vector_ptrtype & vector, bool use_scalar_one=false ) const
146  {
147  int size1 = M_functionals1.size();
148  int size2 = M_functionals2.size();
149  bool size_error=false;
150  if( size1 > 0 && size2 > 0 )
151  size_error=true;
152  if( (size1 + size2) == 0 )
153  size_error=true;
154 
155  FEELPP_ASSERT( !size_error )( size1 )( size2 ).error( "FsFunctionalLinearComposite has no elements, or both maps have elements" );
156 
157  if( size1 > 0 )
158  sumAllVectors1( vector, use_scalar_one );
159  else
160  sumAllVectors2( vector, use_scalar_one );
161  }
162 
163 
164  void sumAllVectors1( vector_ptrtype & vector, bool use_scalar_one=false ) const
165  {
166  int size1 = M_functionals1.size();
167  int size2 = M_functionals2.size();
168 
169  FEELPP_ASSERT( size1 > 0 )( size1 )( size2 ).error( "FsFunctionalLinearComposite has no elements" );
170 
171  vector->zero();
172  auto temp_vector = M_backend->newVector( this->space() );
173  auto end = M_functionals1.end();
174  for(auto it=M_functionals1.begin(); it!=end; ++it)
175  {
176  int position = it->first;
177  double scalar=1;
178  if( ! use_scalar_one )
179  scalar = M_scalars1[position];
180  it->second->containerPtr(temp_vector);
181  vector->add( scalar , temp_vector );
182  }
183 
184  }//sumAllVectors
185 
186  void sumAllVectors2( vector_ptrtype & vector, bool use_scalar_one=false ) const
187  {
188  int size1 = M_functionals1.size();
189  int size2 = M_functionals2.size();
190 
191  FEELPP_ASSERT( size2 > 0 )( size1 )( size2 ).error( "FsFunctionalLinearComposite has no elements" );
192 
193  vector->zero();
194  auto temp_vector = M_backend->newVector( this->space() );
195  auto end = M_functionals2.end();
196  for(auto it=M_functionals2.begin(); it!=end; ++it)
197  {
198  auto position = it->first;
199  int q = position.template get<0>();
200  int m = position.template get<1>();
201  double scalar=1;
202  if( ! use_scalar_one )
203  scalar = M_scalars2[q][m];
204  it->second->containerPtr(temp_vector);
205  vector->add( scalar , temp_vector );
206  }
207 
208  }//sumAllVectors
209 
210 
211  super_ptrtype& functionallinear( int q )
212  {
213  int q_max = M_functionals1.size();
214  FEELPP_ASSERT( q < q_max )( q_max )( q ).error( "FsFunctionalLinearComposite has not enough elements" );
215  return M_functionals1.template at(q);
216  }
217 
218  super_ptrtype& functionallinear( int q , int m)
219  {
220  auto tuple = boost::make_tuple( q , m );
221  return M_functionals2.template at(tuple);
222  }
223 
224 
225  //Access to a specific vector
226  void vecPtr( int q , vector_ptrtype& vector )
227  {
228  int q_max = M_functionals1.size();
229  FEELPP_ASSERT( q < q_max )( q_max )( q ).error( "FsFunctionalLinearComposite has not enough elements" );
230  //auto vector = M_backend->newVector( this->space() );
231  M_functionals1.template at(q)->containerPtr(vector);
232  //return vector;
233  }
234 
235  void vecPtr( int q , vector_ptrtype& vector ) const
236  {
237  int q_max = M_functionals1.size();
238  FEELPP_ASSERT( q < q_max )( q_max )( q ).error( "FsFunctionalLinearComposite has not enough elements" );
239  M_functionals1.template at(q)->containerPtr(vector);
240  }
241 
242  //Access to a specific vector
243  void vecPtr( int q , int m , vector_ptrtype& vector )
244  {
245  auto tuple = boost::make_tuple( q , m );
246  M_functionals2.template at(tuple)->containerPtr(vector);
247  }
248 
249  void vecPtr( int q , int m , vector_ptrtype& vector ) const
250  {
251  auto tuple = boost::make_tuple( q , m );
252  M_functionals2.template at(tuple)->containerPtr(vector);
253  }
254 
255 
256  //return the sum of all vectors
257  virtual void containerPtr( vector_ptrtype & vector_to_fill )
258  {
259  //vector_to_fill = sumAllVectors(true);
260  sumAllVectors( vector_to_fill , true );
261  vector_to_fill->close();
262  }
263 
264  // apply the functional
265  virtual value_type
266  operator()( const element_type& x ) const
267  {
268  //auto vector = sumAllVectors( true );
269  auto vector = M_backend->newVector( this->space() );
270  sumAllVectors( vector, true );
271  vector->close();
272  return M_backend->dot( *vector, x.container() );
273  }
274 
275 
276 private:
277 
278  std::map< int, super_ptrtype > M_functionals1;
279  std::map< boost::tuple<int,int> , super_ptrtype > M_functionals2;
280  backend_ptrtype M_backend;
281  std::vector< double > M_scalars1;
282  std::vector< std::vector<double> > M_scalars2;
283 };
284 
285 namespace detail
286 {
287 
288 template<typename Args>
289 struct compute_functionalLinearComposite_return
290 {
291  typedef typename boost::remove_reference<typename parameter::binding<Args, tag::space>::type>::type::element_type space_type;
292 
293  typedef FsFunctionalLinearComposite<space_type> type;
294  typedef boost::shared_ptr<FsFunctionalLinearComposite<space_type> > ptrtype;
295 };
296 }
297 
298 BOOST_PARAMETER_FUNCTION(
299  ( typename Feel::detail::compute_functionalLinearComposite_return<Args>::ptrtype ), // 1. return type
300  functionalLinearComposite, // 2. name of the function template
301  tag, // 3. namespace of tag types
302  ( required
303  ( space, *( boost::is_convertible<mpl::_,boost::shared_ptr<FunctionSpaceBase> > ) )
304  ) // required
305  ( optional
306  ( backend, *, Backend<typename Feel::detail::compute_functionalLinearComposite_return<Args>::space_type::value_type>::build() )
307  ) // optionnal
308 )
309 {
310 
311  Feel::detail::ignore_unused_variable_warning( args );
312  typedef typename Feel::detail::compute_functionalLinearComposite_return<Args>::type functionalcomposite_type;
313  typedef typename Feel::detail::compute_functionalLinearComposite_return<Args>::ptrtype functionalcomposite_ptrtype;
314  return functionalcomposite_ptrtype ( new functionalcomposite_type( space , backend ) );
315 
316 } // functionalLinearComposite
317 
318 }//Feel
319 
320 
321 #endif /* _FSFUNCTIONALLINEARCOMPOSITE_HPP_ */

Generated on Sun Oct 20 2013 08:24:57 for Feel++ by doxygen 1.8.4