$extrastylesheet
raw_accessor.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 #ifndef LIBMESH_RAW_ACCESSOR_H
00021 #define LIBMESH_RAW_ACCESSOR_H
00022 
00023 // Local includes
00024 #include "libmesh/libmesh_common.h"
00025 
00026 #include "libmesh/tensor_value.h"
00027 #include "libmesh/vector_value.h"
00028 #include "libmesh/type_n_tensor.h"
00029 
00030 namespace libMesh
00031 {
00032 
00036 template <typename FieldType>
00037 struct RawFieldType {};
00038 
00039 template <>
00040 struct RawFieldType<Number>
00041 {
00042   typedef Number type;
00043 };
00044 
00045 template <>
00046 struct RawFieldType<Gradient>
00047 {
00048   typedef Number type;
00049 };
00050 
00051 template <>
00052 struct RawFieldType<Tensor>
00053 {
00054   typedef Number type;
00055 };
00056 
00057 template<>
00058 struct RawFieldType<TypeNTensor<3, Number> >
00059 {
00060   typedef Number type;
00061 };
00062 
00063 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
00064 template <>
00065 struct RawFieldType<Real>
00066 {
00067   typedef Real type;
00068 };
00069 
00070 template <>
00071 struct RawFieldType<RealGradient>
00072 {
00073   typedef Real type;
00074 };
00075 
00076 template <>
00077 struct RawFieldType<RealTensor>
00078 {
00079   typedef Real type;
00080 };
00081 
00082 template<>
00083 struct RawFieldType<TypeNTensor<3, Real> >
00084 {
00085   typedef Real type;
00086 };
00087 #endif
00088 
00092 template <typename FieldType>
00093 class RawAccessor
00094 {
00095 public:
00096 
00097   RawAccessor( FieldType& data, const unsigned int dim )
00098     : _data(data),
00099       _dim(dim)
00100   {}
00101 
00102   ~RawAccessor(){}
00103 
00104   typename RawFieldType<FieldType>::type& operator()( unsigned int i );
00105   const typename RawFieldType<FieldType>::type& operator()( unsigned int i ) const;
00106 
00107 private:
00108   RawAccessor();
00109 
00110   FieldType& _data;
00111   const unsigned int _dim;
00112 };
00113 
00114 // Specialize for specific cases
00115 template<>
00116 inline
00117 Number& RawAccessor<Number>::operator()( unsigned int libmesh_dbg_var(i) )
00118 {
00119   libmesh_assert_equal_to (i, 0);
00120   return this->_data;
00121 }
00122 
00123 template<>
00124 inline
00125 Number& RawAccessor<Gradient>::operator()( unsigned int i )
00126 {
00127   libmesh_assert_less (i, this->_dim);
00128   return this->_data(i);
00129 }
00130 
00131 template<>
00132 inline
00133 Number& RawAccessor<Tensor>::operator()( unsigned int k )
00134 {
00135   libmesh_assert_less (k, this->_dim*this->_dim);
00136 
00137   // For tensors, each row is filled first, i.e. for 2-D
00138   // [ 0 1; 2 3]
00139   // Thus, k(i,j) = j + i*dim
00140   unsigned int ii = k/_dim;
00141   unsigned int jj = k - ii*_dim;
00142 
00143   return this->_data(ii,jj);
00144 }
00145 
00149 template <unsigned int N, typename ScalarType>
00150 class RawAccessor<TypeNTensor<N, ScalarType> >
00151 {
00152 public:
00153 
00154   typedef TypeNTensor<N, ScalarType> FieldType;
00155 
00156   RawAccessor( FieldType& data, const unsigned int dim )
00157     : _data(data),
00158       _dim(dim)
00159   {}
00160 
00161   ~RawAccessor(){}
00162 
00163   typename RawFieldType<FieldType>::type& operator()( unsigned int /*i*/ )
00164   { return dummy; }
00165 
00166   const typename RawFieldType<FieldType>::type& operator()( unsigned int /*i*/ ) const
00167   { return dummy; }
00168 
00169 private:
00170   RawAccessor();
00171 
00172   ScalarType dummy;
00173 
00174   FieldType& _data;
00175   const unsigned int _dim;
00176 };
00177 
00178 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
00179 template<>
00180 inline
00181 Real& RawAccessor<Real>::operator()( unsigned int i )
00182 {
00183   libmesh_assert_equal_to (i, 0);
00184   return this->_data;
00185 }
00186 
00187 template<>
00188 inline
00189 Real& RawAccessor<RealGradient>::operator()( unsigned int i )
00190 {
00191   libmesh_assert_less (i, this->_dim);
00192   return this->_data(i);
00193 }
00194 
00195 template<>
00196 inline
00197 Real& RawAccessor<RealTensor>::operator()( unsigned int k )
00198 {
00199   libmesh_assert_less (k, this->_dim*this->_dim);
00200 
00201   // For tensors, each row is filled first, i.e. for 2-D
00202   // [ 0 1; 2 3]
00203   // Thus, k(i,j) = i + j*dim
00204   unsigned int jj = k/_dim;
00205   unsigned int ii = k - jj*_dim;
00206 
00207   return this->_data(ii,jj);
00208 }
00209 
00210 #endif
00211 
00212 }
00213 #endif // LIBMESH_RAW_ACCESSOR_H