1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ALBERTA_DOFVECTOR_HH
4 #define DUNE_ALBERTA_DOFVECTOR_HH
5 
6 #include <cstdlib>
7 #include <limits>
8 
9 #include <dune/grid/albertagrid/misc.hh>
10 #include <dune/grid/albertagrid/elementinfo.hh>
11 #include <dune/grid/albertagrid/refinement.hh>
12 
13 #if HAVE_ALBERTA
14 
15 namespace Dune
16 {
17 
18   namespace Alberta
19   {
20 
21     // External Forward Declarations
22     // -----------------------------
23 
24     template< int dim >
25     class MeshPointer;
26 
27 
28 
29     // DofVectorProvider
30     // -----------------
31 
32     template< class Dof >
33     struct DofVectorProvider;
34 
35     template<>
36     struct DofVectorProvider< int >
37     {
38       typedef ALBERTA DOF_INT_VEC DofVector;
39 
getDune::Alberta::DofVectorProvider40       static DofVector *get ( const DofSpace *dofSpace, const std::string &name )
41       {
42         return ALBERTA get_dof_int_vec( name.c_str(), dofSpace );
43       }
44 
freeDune::Alberta::DofVectorProvider45       static void free ( DofVector *dofVector )
46       {
47         ALBERTA free_dof_int_vec( dofVector );
48       }
49 
readDune::Alberta::DofVectorProvider50       static DofVector *read ( const std::string &filename, Mesh *mesh, DofSpace *dofSpace )
51       {
52         return ALBERTA read_dof_int_vec_xdr( filename.c_str(), mesh, dofSpace );
53       }
54 
writeDune::Alberta::DofVectorProvider55       static bool write ( const DofVector *dofVector, const std::string &filename )
56       {
57         int success = ALBERTA write_dof_int_vec_xdr( dofVector, filename.c_str() );
58         return (success == 0);
59       }
60     };
61 
62     template<>
63     struct DofVectorProvider< signed char >
64     {
65       typedef ALBERTA DOF_SCHAR_VEC DofVector;
66 
getDune::Alberta::DofVectorProvider67       static DofVector *get ( const DofSpace *dofSpace, const std::string &name )
68       {
69         return ALBERTA get_dof_schar_vec( name.c_str(), dofSpace );
70       }
71 
freeDune::Alberta::DofVectorProvider72       static void free ( DofVector *dofVector )
73       {
74         ALBERTA free_dof_schar_vec( dofVector );
75       }
76 
readDune::Alberta::DofVectorProvider77       static DofVector *read ( const std::string &filename, Mesh *mesh, DofSpace *dofSpace )
78       {
79         return ALBERTA read_dof_schar_vec_xdr( filename.c_str(), mesh, dofSpace );
80       }
81 
writeDune::Alberta::DofVectorProvider82       static bool write ( const DofVector *dofVector, const std::string &filename )
83       {
84         int success = ALBERTA write_dof_schar_vec_xdr( dofVector, filename.c_str() );
85         return (success == 0);
86       }
87     };
88 
89     template<>
90     struct DofVectorProvider< unsigned char >
91     {
92       typedef ALBERTA DOF_UCHAR_VEC DofVector;
93 
getDune::Alberta::DofVectorProvider94       static DofVector *get ( const DofSpace *dofSpace, const std::string &name )
95       {
96         return ALBERTA get_dof_uchar_vec( name.c_str(), dofSpace );
97       }
98 
freeDune::Alberta::DofVectorProvider99       static void free ( DofVector *dofVector )
100       {
101         ALBERTA free_dof_uchar_vec( dofVector );
102       }
103 
readDune::Alberta::DofVectorProvider104       static DofVector *read ( const std::string &filename, Mesh *mesh, DofSpace *dofSpace )
105       {
106         return ALBERTA read_dof_uchar_vec_xdr( filename.c_str(), mesh, dofSpace );
107       }
108 
writeDune::Alberta::DofVectorProvider109       static bool write ( const DofVector *dofVector, const std::string &filename )
110       {
111         int success = ALBERTA write_dof_uchar_vec_xdr( dofVector, filename.c_str() );
112         return (success == 0);
113       }
114     };
115 
116     template<>
117     struct DofVectorProvider< Real >
118     {
119       typedef ALBERTA DOF_REAL_VEC DofVector;
120 
getDune::Alberta::DofVectorProvider121       static DofVector *get ( const DofSpace *dofSpace, const std::string &name )
122       {
123         return ALBERTA get_dof_real_vec( name.c_str(), dofSpace );
124       }
125 
freeDune::Alberta::DofVectorProvider126       static void free ( DofVector *dofVector )
127       {
128         ALBERTA free_dof_real_vec( dofVector );
129       }
130 
readDune::Alberta::DofVectorProvider131       static DofVector *read ( const std::string &filename, Mesh *mesh, DofSpace *dofSpace )
132       {
133         return ALBERTA read_dof_real_vec_xdr( filename.c_str(), mesh, dofSpace );
134       }
135 
writeDune::Alberta::DofVectorProvider136       static bool write ( const DofVector *dofVector, const std::string &filename )
137       {
138         int success = ALBERTA write_dof_real_vec_xdr( dofVector, filename.c_str() );
139         return (success == 0);
140       }
141     };
142 
143     template<>
144     struct DofVectorProvider< GlobalVector >
145     {
146       typedef ALBERTA DOF_REAL_D_VEC DofVector;
147 
getDune::Alberta::DofVectorProvider148       static DofVector *get ( const DofSpace *dofSpace, const std::string &name )
149       {
150         return ALBERTA get_dof_real_d_vec( name.c_str(), dofSpace );
151       }
152 
freeDune::Alberta::DofVectorProvider153       static void free ( DofVector *dofVector )
154       {
155         ALBERTA free_dof_real_d_vec( dofVector );
156       }
157 
readDune::Alberta::DofVectorProvider158       static DofVector *read ( const std::string &filename, Mesh *mesh, DofSpace *dofSpace )
159       {
160         return ALBERTA read_dof_real_d_vec_xdr( filename.c_str(), mesh, dofSpace );
161       }
162 
writeDune::Alberta::DofVectorProvider163       static bool write ( const DofVector *dofVector, const std::string &filename )
164       {
165         int success = ALBERTA write_dof_real_d_vec_xdr( dofVector, filename.c_str() );
166         return (success == 0);
167       }
168     };
169 
170 
171 
172     // DofVectorPointer
173     // ----------------
174 
175     template< class Dof >
176     class DofVectorPointer
177     {
178       typedef DofVectorPointer< Dof > This;
179 
180       typedef Alberta::DofVectorProvider< Dof > DofVectorProvider;
181 
182     public:
183       typedef typename DofVectorProvider::DofVector DofVector;
184 
185       static const bool supportsAdaptationData = true;
186 
187     private:
188       DofVector *dofVector_;
189 
190     public:
DofVectorPointer()191       DofVectorPointer ()
192         : dofVector_( NULL )
193       {}
194 
DofVectorPointer(const DofSpace * dofSpace,const std::string & name="")195       explicit DofVectorPointer ( const DofSpace *dofSpace,
196                                   const std::string &name = "" )
197         : dofVector_ ( DofVectorProvider::get( dofSpace, name ) )
198       {}
199 
DofVectorPointer(DofVector * dofVector)200       explicit DofVectorPointer ( DofVector *dofVector )
201         : dofVector_( dofVector )
202       {}
203 
operator bool() const204       explicit operator bool () const
205       {
206         return (bool)dofVector_;
207       }
208 
operator DofVector*() const209       operator DofVector * () const
210       {
211         return dofVector_;
212       }
213 
operator Dof*() const214       operator Dof * () const
215       {
216         Dof *ptr = NULL;
217         GET_DOF_VEC( ptr, dofVector_ );
218         return ptr;
219       }
220 
dofSpace() const221       const DofSpace *dofSpace () const
222       {
223         return dofVector_->fe_space;
224       }
225 
name() const226       std::string name () const
227       {
228         if( dofVector_ )
229           return dofVector_->name;
230         else
231           return std::string();
232       }
233 
create(const DofSpace * dofSpace,const std::string & name="")234       void create ( const DofSpace *dofSpace, const std::string &name = "" )
235       {
236         release();
237         dofVector_ = DofVectorProvider::get( dofSpace, name );
238       }
239 
240       template< int dim >
read(const std::string & filename,const MeshPointer<dim> & meshPointer)241       void read ( const std::string &filename, const MeshPointer< dim > &meshPointer )
242       {
243         release();
244         dofVector_ = DofVectorProvider::read( filename, meshPointer, NULL );
245       }
246 
write(const std::string & filename) const247       bool write ( const std::string &filename ) const
248       {
249         return DofVectorProvider::write( dofVector_, filename );
250       }
251 
release()252       void release ()
253       {
254         if( dofVector_ )
255         {
256           DofVectorProvider::free( dofVector_ );
257           dofVector_ = NULL;
258         }
259       }
260 
261       template< class Functor >
forEach(Functor & functor) const262       void forEach ( Functor &functor ) const
263       {
264         Dof *array = (Dof *)(*this);
265         FOR_ALL_DOFS( dofSpace()->admin, functor( array[ dof ] ) );
266       }
267 
initialize(const Dof & value)268       void initialize ( const Dof &value )
269       {
270         Dof *array = (Dof *)(*this);
271         FOR_ALL_DOFS( dofSpace()->admin, array[ dof ] = value );
272       }
273 
274       template< class AdaptationData >
getAdaptationData() const275       AdaptationData *getAdaptationData () const
276       {
277         assert( dofVector_ );
278         assert( dofVector_->user_data );
279         return static_cast< AdaptationData * >( dofVector_->user_data );
280       }
281 
282       template< class AdaptationData >
setAdaptationData(AdaptationData * adaptationData)283       void setAdaptationData ( AdaptationData *adaptationData )
284       {
285         assert( dofVector_ );
286         dofVector_->user_data = adaptationData;
287       }
288 
289       template< class Interpolation >
setupInterpolation()290       void setupInterpolation ()
291       {
292         assert( dofVector_ );
293         dofVector_->refine_interpol = &refineInterpolate< Interpolation >;
294       }
295 
296       template< class Restriction >
setupRestriction()297       void setupRestriction ()
298       {
299         assert( dofVector_ );
300         dofVector_->coarse_restrict = &coarsenRestrict< Restriction >;
301       }
302 
303     private:
304       template< class Interpolation >
refineInterpolate(DofVector * dofVector,RC_LIST_EL * list,int n)305       static void refineInterpolate ( DofVector *dofVector, RC_LIST_EL *list, int n )
306       {
307         const This dofVectorPointer( dofVector );
308         typename Interpolation::Patch patch( list, n );
309         Interpolation::interpolateVector( dofVectorPointer, patch );
310       }
311 
312       template< class Restriction >
coarsenRestrict(DofVector * dofVector,RC_LIST_EL * list,int n)313       static void coarsenRestrict ( DofVector *dofVector, RC_LIST_EL *list, int n )
314       {
315         const This dofVectorPointer( dofVector );
316         typename Restriction::Patch patch( list, n );
317         Restriction::restrictVector( dofVectorPointer, patch );
318       }
319     };
320 
321 
322 
323     // Auxiliary Functions
324     // --------------------
325 
abs(const DofVectorPointer<int> & dofVector)326     inline void abs ( const DofVectorPointer< int > &dofVector )
327     {
328       assert( !dofVector == false );
329       int *array = (int *)dofVector;
330       FOR_ALL_DOFS( dofVector.dofSpace()->admin,
331                     array[ dof ] = std::abs( array[ dof ] ) );
332     }
333 
334 
max(const DofVectorPointer<int> & dofVector)335     inline int max ( const DofVectorPointer< int > &dofVector )
336     {
337       assert( !dofVector == false );
338       int *array = (int *)dofVector;
339       int result = std::numeric_limits< int >::min();
340       FOR_ALL_DOFS( dofVector.dofSpace()->admin,
341                     result = std::max( result, array[ dof ] ) );
342       return result;
343     }
344 
345 
min(const DofVectorPointer<int> & dofVector)346     inline int min ( const DofVectorPointer< int > &dofVector )
347     {
348       assert( !dofVector == false );
349       int *array = (int *)dofVector;
350       int result = std::numeric_limits< int >::max();
351       FOR_ALL_DOFS( dofVector.dofSpace()->admin,
352                     result = std::min( result, array[ dof ] ) );
353       return result;
354     }
355 
356   } // namespace Alberta
357 
358 } // namespace Dune
359 
360 #endif // #if HAVE_ALBERTA
361 
362 #endif // #ifndef DUNE_ALBERTA_DOFVECTOR_HH
363