dune-grid
2.2.0
|
00001 #ifndef DUNE_ALBERTA_NODEPROJECTION_HH 00002 #define DUNE_ALBERTA_NODEPROJECTION_HH 00003 00004 #include <dune/common/shared_ptr.hh> 00005 00006 #include <dune/grid/common/boundaryprojection.hh> 00007 00008 #include <dune/grid/albertagrid/misc.hh> 00009 #include <dune/grid/albertagrid/elementinfo.hh> 00010 00011 #if HAVE_ALBERTA 00012 00013 namespace Dune 00014 { 00015 00016 namespace Alberta 00017 { 00018 00019 // Internal Forward Declarations 00020 // ----------------------------- 00021 00022 template< class Proj, class Impl > 00023 class ProjectionFactory; 00024 00025 00026 00027 // DuneBoundaryProjection 00028 // ---------------------- 00029 00030 template< int dim > 00031 class DuneBoundaryProjection 00032 { 00033 typedef DuneBoundaryProjection< dim > This; 00034 00035 public: 00036 static const int dimension = dim; 00037 00038 typedef Alberta::ElementInfo< dimension > ElementInfo; 00039 typedef FieldVector< Real, dimWorld > GlobalCoordinate; 00040 00041 typedef Dune::DuneBoundaryProjection< dimWorld > Projection; 00042 typedef Dune::shared_ptr< const Projection > ProjectionPtr; 00043 00044 explicit DuneBoundaryProjection ( const ProjectionPtr &projection ) 00045 : projection_( projection ) 00046 {} 00047 00048 // note: GlobalVector is an array type; global is the return value 00049 void operator() ( const ElementInfo &elementInfo, const LocalVector local, 00050 GlobalVector global ) const 00051 { 00052 GlobalCoordinate x; 00053 for( int i = 0; i < dimWorld; ++i ) 00054 x[ i ] = global[ i ]; 00055 GlobalCoordinate y = projection()( x ); 00056 for( int i = 0; i < dimWorld; ++i ) 00057 global[ i ] = y[ i ]; 00058 } 00059 00060 const Projection &projection () const 00061 { 00062 return *projection_; 00063 } 00064 00065 private: 00066 ProjectionPtr projection_; 00067 }; 00068 00069 00070 00071 // ProjectionFactoryInterface 00072 // -------------------------- 00073 00074 template< class Proj, class Impl > 00075 class ProjectionFactoryInterface 00076 { 00077 typedef ProjectionFactoryInterface< Proj, Impl > This; 00078 00079 friend class ProjectionFactory< Proj, Impl >; 00080 00081 public: 00082 typedef Proj Projection; 00083 00084 static const int dimension = Projection::dimension; 00085 00086 typedef Alberta::ElementInfo< dimension > ElementInfo; 00087 00088 private: 00089 ProjectionFactoryInterface () 00090 {} 00091 00092 ProjectionFactoryInterface ( const This &other ); 00093 This &operator= ( const This &other ); 00094 00095 public: 00096 bool hasProjection ( const ElementInfo &elementInfo, const int face ) const 00097 { 00098 return asImpl().hasProjection( elementInfo, face ); 00099 } 00100 00101 bool hasProjection ( const ElementInfo &elementInfo ) const 00102 { 00103 return asImpl().hasProjection( elementInfo ); 00104 } 00105 00106 Projection projection ( const ElementInfo &elementInfo, const int face ) const 00107 { 00108 return asImpl().projection( elementInfo, face ); 00109 }; 00110 00111 Projection projection ( const ElementInfo &elementInfo ) const 00112 { 00113 return asImpl().projection( elementInfo ); 00114 }; 00115 00116 protected: 00117 const Impl &asImpl () const 00118 { 00119 return static_cast< const Impl & >( *this ); 00120 } 00121 }; 00122 00123 00124 00125 // ProjectionFactory 00126 // ----------------- 00127 00128 template< class Proj, class Impl > 00129 class ProjectionFactory 00130 : public ProjectionFactoryInterface< Proj, Impl > 00131 { 00132 typedef ProjectionFactory< Proj, Impl > This; 00133 typedef ProjectionFactoryInterface< Proj, Impl > Base; 00134 00135 public: 00136 typedef typename Base::Projection Projection; 00137 typedef typename Base::ElementInfo ElementInfo; 00138 00139 protected: 00140 ProjectionFactory () 00141 {} 00142 00143 private: 00144 bool hasProjection ( const ElementInfo &elementInfo, const int face ) const; 00145 bool hasProjection ( const ElementInfo &elementInfo ) const; 00146 00147 Projection projection ( const ElementInfo &elementInfo, const int face ) const; 00148 Projection projection ( const ElementInfo &elementInfo ) const; 00149 }; 00150 00151 00152 00153 // DuneGlobalBoundaryProjectionFactory 00154 // ----------------------------------- 00155 00156 template< int dim > 00157 class DuneGlobalBoundaryProjectionFactory 00158 : public ProjectionFactory< DuneBoundaryProjection< dim >, DuneGlobalBoundaryProjectionFactory< dim > > 00159 { 00160 typedef DuneGlobalBoundaryProjectionFactory< dim > This; 00161 typedef ProjectionFactory< DuneBoundaryProjection< dim >, This > Base; 00162 00163 public: 00164 typedef typename Base::Projection Projection; 00165 typedef typename Base::ElementInfo ElementInfo; 00166 00167 typedef typename Projection::ProjectionPtr DuneProjectionPtr; 00168 00169 DuneGlobalBoundaryProjectionFactory ( const DuneProjectionPtr &projection ) 00170 : projection_( projection ) 00171 {} 00172 00173 bool hasProjection ( const ElementInfo &elementInfo, const int face ) const 00174 { 00175 return true; 00176 } 00177 00178 bool hasProjection ( const ElementInfo &elementInfo ) const 00179 { 00180 return true; 00181 } 00182 00183 Projection projection ( const ElementInfo &elementInfo, const int face ) const 00184 { 00185 return projection_; 00186 }; 00187 00188 Projection projection ( const ElementInfo &elementInfo ) const 00189 { 00190 return projection_; 00191 }; 00192 00193 private: 00194 const Projection projection_; 00195 }; 00196 00197 00198 00199 // BasicNodeProjection 00200 // ------------------- 00201 00202 struct BasicNodeProjection 00203 : public ALBERTA NODE_PROJECTION 00204 { 00205 explicit BasicNodeProjection ( unsigned int boundaryIndex ) 00206 : boundaryIndex_( boundaryIndex ) 00207 { 00208 func = 0; 00209 } 00210 00211 virtual ~BasicNodeProjection () 00212 {} 00213 00214 unsigned int boundaryIndex () const 00215 { 00216 return boundaryIndex_; 00217 } 00218 00219 private: 00220 unsigned int boundaryIndex_; 00221 }; 00222 00223 00224 00225 // NodeProjection 00226 // -------------- 00227 00228 template< int dim, class Projection > 00229 class NodeProjection 00230 : public BasicNodeProjection 00231 { 00232 typedef NodeProjection< dim, Projection > This; 00233 typedef BasicNodeProjection Base; 00234 00235 public: 00236 static const int dimension = dim; 00237 00238 typedef Alberta::ElementInfo< dimension > ElementInfo; 00239 00240 private: 00241 Projection projection_; 00242 00243 public: 00244 NodeProjection ( unsigned int boundaryIndex, const Projection &projection ) 00245 : Base( boundaryIndex ), 00246 projection_( projection ) 00247 { 00248 func = apply; 00249 } 00250 00251 private: 00252 // note: global is the return type (it is an array type and hence no 00253 // reference is needed) 00254 static void apply ( GlobalVector global, const EL_INFO *info, const LocalVector local ) 00255 { 00256 const ElementInfo elementInfo = ElementInfo::createFake( *info ); 00257 00258 assert( (info->fill_flag & FillFlags< dimension >::projection) != 0 ); 00259 const This *nodeProjection = static_cast< const This * >( info->active_projection ); 00260 00261 assert( nodeProjection != NULL ); 00262 nodeProjection->projection_( elementInfo, local, global ); 00263 } 00264 }; 00265 00266 } 00267 00268 } 00269 00270 #endif // #if HAVE_ALBERTA 00271 00272 #endif // #ifndef DUNE_ALBERTA_NODEPROJECTION_HH