30 #ifndef __FSFUNCTIONALLINEARCOMPOSITE_H
31 #define __FSFUNCTIONALLINEARCOMPOSITE_H 1
41 class FsFunctionalLinearComposite :
public FsFunctionalLinear<Space>
46 typedef FsFunctionalLinearComposite<Space> this_type;
47 typedef FsFunctionalLinear<Space> super_type;
48 typedef boost::shared_ptr<super_type> super_ptrtype;
50 typedef Space space_type;
52 typedef boost::shared_ptr<space_type> space_ptrtype;
53 typedef typename space_type::element_type element_type;
55 typedef typename space_type::value_type value_type;
57 typedef Backend<value_type> backend_type;
58 typedef boost::shared_ptr<backend_type> backend_ptrtype;
60 typedef typename backend_type::vector_type vector_type;
61 typedef typename backend_type::vector_ptrtype vector_ptrtype;
63 FsFunctionalLinearComposite( space_ptrtype space ) :
65 M_backend( backend_type::build( BACKEND_PETSC ) )
68 FsFunctionalLinearComposite( space_ptrtype space, backend_ptrtype backend ) :
75 int size1 = M_functionals1.size();
76 int size2 = M_functionals2.size();
83 void addElement( super_ptrtype
const& functional )
85 int size = M_functionals1.size();
86 M_functionals1.insert( std::make_pair( size , functional ) ) ;
89 void addElement(
int q, super_ptrtype
const& functional )
91 M_functionals1.insert( std::make_pair( q , functional ) ) ;
94 void addList( std::vector< super_ptrtype >
const& vec )
97 for(
int q=0; q<q_max; q++)
104 void addElement( boost::tuple<int,int>
const& qm , super_ptrtype
const& functional )
106 M_functionals2.insert( std::make_pair( qm , functional ) );
109 void addList( std::vector< std::vector< super_ptrtype > >
const& vec )
111 int q_max = vec.size();
112 for(
int q=0; q<q_max; q++)
114 int m_max = vec[q].size();
115 for(
int m=0; m<m_max; m++)
117 auto tuple = boost::make_tuple( q , m );
124 void setScalars( std::vector<double> scalars )
126 M_scalars1 = scalars;
129 void setScalars( std::vector< std::vector< double > > scalars )
131 M_scalars2 = scalars;
134 this_type&
operator=( this_type
const& m )
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;
145 void sumAllVectors( vector_ptrtype & vector,
bool use_scalar_one=
false )
const
147 int size1 = M_functionals1.size();
148 int size2 = M_functionals2.size();
149 bool size_error=
false;
150 if( size1 > 0 && size2 > 0 )
152 if( (size1 + size2) == 0 )
155 FEELPP_ASSERT( !size_error )( size1 )( size2 ).error(
"FsFunctionalLinearComposite has no elements, or both maps have elements" );
158 sumAllVectors1( vector, use_scalar_one );
160 sumAllVectors2( vector, use_scalar_one );
164 void sumAllVectors1( vector_ptrtype & vector,
bool use_scalar_one=
false )
const
166 int size1 = M_functionals1.size();
167 int size2 = M_functionals2.size();
169 FEELPP_ASSERT( size1 > 0 )( size1 )( size2 ).error(
"FsFunctionalLinearComposite has no elements" );
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)
176 int position = it->first;
178 if( ! use_scalar_one )
179 scalar = M_scalars1[position];
180 it->second->containerPtr(temp_vector);
181 vector->add( scalar , temp_vector );
186 void sumAllVectors2( vector_ptrtype & vector,
bool use_scalar_one=
false )
const
188 int size1 = M_functionals1.size();
189 int size2 = M_functionals2.size();
191 FEELPP_ASSERT( size2 > 0 )( size1 )( size2 ).error(
"FsFunctionalLinearComposite has no elements" );
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)
198 auto position = it->first;
199 int q = position.template get<0>();
200 int m = position.template get<1>();
202 if( ! use_scalar_one )
203 scalar = M_scalars2[q][m];
204 it->second->containerPtr(temp_vector);
205 vector->add( scalar , temp_vector );
211 super_ptrtype& functionallinear(
int q )
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);
218 super_ptrtype& functionallinear(
int q ,
int m)
220 auto tuple = boost::make_tuple( q , m );
221 return M_functionals2.template at(tuple);
226 void vecPtr(
int q , vector_ptrtype& vector )
228 int q_max = M_functionals1.size();
229 FEELPP_ASSERT( q < q_max )( q_max )( q ).error(
"FsFunctionalLinearComposite has not enough elements" );
231 M_functionals1.template at(q)->containerPtr(vector);
235 void vecPtr(
int q , vector_ptrtype& vector )
const
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);
243 void vecPtr(
int q ,
int m , vector_ptrtype& vector )
245 auto tuple = boost::make_tuple( q , m );
246 M_functionals2.template at(tuple)->containerPtr(vector);
249 void vecPtr(
int q ,
int m , vector_ptrtype& vector )
const
251 auto tuple = boost::make_tuple( q , m );
252 M_functionals2.template at(tuple)->containerPtr(vector);
257 virtual void containerPtr( vector_ptrtype & vector_to_fill )
260 sumAllVectors( vector_to_fill ,
true );
261 vector_to_fill->close();
266 operator()(
const element_type& x )
const
269 auto vector = M_backend->newVector( this->space() );
270 sumAllVectors( vector,
true );
272 return M_backend->dot( *vector, x.container() );
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;
288 template<
typename Args>
289 struct compute_functionalLinearComposite_return
291 typedef typename boost::remove_reference<typename parameter::binding<Args, tag::space>::type>::type::element_type space_type;
293 typedef FsFunctionalLinearComposite<space_type> type;
294 typedef boost::shared_ptr<FsFunctionalLinearComposite<space_type> > ptrtype;
298 BOOST_PARAMETER_FUNCTION(
299 (
typename Feel::detail::compute_functionalLinearComposite_return<Args>::ptrtype ),
300 functionalLinearComposite,
303 ( space, *( boost::is_convertible<mpl::_,boost::shared_ptr<FunctionSpaceBase> > ) )
306 ( backend, *, Backend<
typename Feel::detail::compute_functionalLinearComposite_return<Args>::space_type::value_type>::build() )
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 ) );