• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List

/export/development/ViennaFEM/viennafem/cell_quan.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAFEM_CELL_QUAN_HPP
00002 #define VIENNAFEM_CELL_QUAN_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2012, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008                              -----------------
00009                ViennaFEM - The Vienna Finite Element Method Library
00010                              -----------------
00011 
00012    Author:     Karl Rupp                          rupp@iue.tuwien.ac.at
00013 
00014    License:    MIT (X11), see file LICENSE in the ViennaFEM base directory
00015 ============================================================================ */
00016 
00017 #include "viennafem/forwards.h"
00018 
00019 #include "viennamath/forwards.h"
00020 #include "viennamath/manipulation/substitute.hpp"
00021 #include "viennamath/expression.hpp"
00022 #include "viennadata/api.hpp"
00023 
00028 namespace viennafem
00029 {
00030   namespace detail
00031   {
00037     template <typename CellType, typename NumericT = viennafem::numeric_type>
00038     class cell_quan_interface
00039     {
00040       protected:
00041         typedef NumericT          numeric_type;
00042         
00043       public: 
00044         virtual numeric_type eval(CellType const & cell, numeric_type v) const = 0;
00045         virtual numeric_type eval(CellType const & cell, std::vector<numeric_type> const & v) const = 0;
00046         
00047         virtual cell_quan_interface<CellType, NumericT> * clone() const = 0;
00048     };
00049 
00056     template <typename CellType, typename KeyType, typename DataType>
00057     class cell_quan_constant : public cell_quan_interface<CellType>
00058     {
00059         typedef cell_quan_constant<CellType, KeyType, DataType>         self_type;
00060         typedef typename cell_quan_interface<CellType>::numeric_type    numeric_type;
00061       
00062       public:
00063         cell_quan_constant(KeyType const & key) : key_(key) {}
00064         
00065         numeric_type eval(CellType const & cell, numeric_type v) const
00066         {
00067           return viennadata::access<KeyType, DataType>(key_)(cell);
00068         }
00069 
00070         numeric_type eval(CellType const & cell, std::vector<numeric_type> const & v) const
00071         {
00072           return viennadata::access<KeyType, DataType>(key_)(cell);
00073         }
00074 
00075         cell_quan_interface<CellType> * clone() const { return new self_type(key_); }
00076         
00077       private:
00078         KeyType key_;
00079     };
00080     
00087     template <typename CellType, typename KeyType, typename DataType>
00088     class cell_quan_expr : public cell_quan_interface<CellType>
00089     {
00090         typedef cell_quan_expr<CellType, KeyType, DataType>             self_type;
00091         typedef typename cell_quan_interface<CellType>::numeric_type    numeric_type;
00092       
00093       public:
00094         cell_quan_expr(KeyType const & key) : key_(key) {}
00095         
00096         numeric_type eval(CellType const & cell, numeric_type v) const
00097         {
00098           return viennadata::access<KeyType, DataType>(key_)(cell)(v);
00099         }
00100 
00101         numeric_type eval(CellType const & cell, std::vector<numeric_type> const & v) const
00102         {
00103           return viennadata::access<KeyType, DataType>(key_)(cell)(v);
00104         }
00105 
00106         cell_quan_interface<CellType> * clone() const { return new self_type(key_); }
00107         
00108       private:
00109         KeyType key_;
00110     };
00111     
00112 
00118     template <typename CellType, typename NumericT = viennafem::numeric_type>
00119     class cell_quan_wrapper
00120     {
00121       public:
00122         template <typename T>
00123         cell_quan_wrapper(T const * t) : functor_(t) {}
00124         
00125         cell_quan_wrapper() {}
00126         
00127         cell_quan_wrapper & operator=(cell_quan_wrapper & other)
00128         {
00129           functor_ = other.functor_;
00130           return *this;
00131         }
00132         
00133         NumericT eval(CellType const & cell,
00134                       numeric_type v) const
00135         {
00136           return functor_->eval(cell, v); 
00137         }
00138 
00139         NumericT eval(CellType const & cell,
00140                       std::vector<numeric_type> const & v) const
00141         {
00142           return functor_->eval(cell, v); 
00143         }
00144 
00145         cell_quan_interface<CellType> * clone() const { return functor_->clone(); }
00146 
00147       private:
00148         std::auto_ptr< const cell_quan_interface<CellType> > functor_;
00149     };
00150 
00151   } //namespace detail
00152   
00153   
00159   template <typename CellType, typename InterfaceType>
00160   class cell_quan : public InterfaceType
00161   {
00162       typedef cell_quan<CellType, InterfaceType>     self_type;
00163       typedef typename InterfaceType::numeric_type            numeric_type;
00164     public:
00165 
00166       explicit cell_quan(CellType const * cell, detail::cell_quan_wrapper<CellType, numeric_type> const & wrapper) : current_cell(cell), accessor(wrapper.clone()) {}
00167       
00168       //template <typename T>
00169       //explicit cell_quan(T const & t) : current_cell(NULL), accessor( new quan_accessor<CellType, T, numeric_type>() ) {}
00170       
00171       explicit cell_quan() : current_cell(NULL) {}
00172 
00173       //interface requirements:
00174       InterfaceType * clone() const { return new self_type(current_cell, accessor); }
00175       numeric_type eval(std::vector<numeric_type> const & v) const
00176       {
00177         return accessor.eval(*current_cell, v);
00178       }
00179       numeric_type eval(numeric_type v) const 
00180       {
00181         return accessor.eval(*current_cell, v);
00182       }
00183       
00184       std::string deep_str() const
00185       {
00186         std::stringstream ss;
00187         ss << "cell_quan(" << current_cell << ")";
00188         return ss.str();      
00189       }
00190       numeric_type unwrap() const { throw "Cannot evaluate unknown_func!"; }
00191       
00192       InterfaceType * substitute(const InterfaceType * e,
00193                                  const InterfaceType * repl) const
00194       {
00195         if (deep_equal(e))
00196           return repl->clone();
00197           
00198         return clone();
00199       };    
00200       
00201       InterfaceType * substitute(std::vector<const InterfaceType *> const &  e,
00202                                  std::vector<const InterfaceType *> const &  repl) const
00203       {
00204         //std::cout << "Comparing variable<" << id << "> with " << e->str() << ", result: ";
00205         for (std::size_t i=0; i<e.size(); ++i)
00206           if (deep_equal(e[i]))
00207             return repl[i]->clone();
00208         
00209         //std::cout << "FALSE" << std::endl;
00210         return clone();
00211       };    
00212       
00213       bool deep_equal(const InterfaceType * other) const
00214       {
00215         //TODO: Include comparison of accessor
00216         return dynamic_cast< const self_type *>(other) != NULL;
00217       }
00218       
00219       bool shallow_equal(const InterfaceType * other) const
00220       {
00221         return dynamic_cast< const self_type *>(other) != NULL;
00222       }
00223       
00224       InterfaceType * diff(const InterfaceType * diff_var) const
00225       {
00226         throw "Cannot differentiate cell_quan!";
00227         return NULL;
00228       }
00229       
00230       
00231       //additional members:
00232       void update(CellType const & cell) const { current_cell = &cell; }
00233       
00234       template <typename T>
00235       void wrap_constant(T const & t) 
00236       {
00237         detail::cell_quan_wrapper<CellType, numeric_type> temp( new detail::cell_quan_constant<CellType, T, numeric_type>(t) );
00238         accessor = temp;
00239       }
00240 
00241       template <typename T>
00242       void wrap_expr(T const & t) 
00243       {
00244         detail::cell_quan_wrapper<CellType, numeric_type> temp( new detail::cell_quan_expr<CellType, T, viennamath::expr>(t) );
00245         accessor = temp;
00246       }
00247       
00248       detail::cell_quan_wrapper<CellType, numeric_type> const & wrapper() const { return accessor; }
00249 
00250     private:
00251       mutable const CellType * current_cell;
00252       detail::cell_quan_wrapper<CellType, numeric_type> accessor;
00253   };
00254 
00255   //TODO: Check whether cell_quan can be injected directly into existing ViennaMath overloads
00256   
00258   template <typename CellType, typename InterfaceType>
00259   viennamath::rt_expr<InterfaceType> operator*(viennamath::rt_variable<InterfaceType> const & lhs,
00260                                cell_quan<CellType, InterfaceType> const & rhs)
00261   {
00262     return viennamath::rt_expr<InterfaceType>(new viennamath::rt_binary_expr<InterfaceType>(lhs.clone(),
00263                                                             new viennamath::op_binary<viennamath::op_mult<viennamath::default_numeric_type>, InterfaceType >(),
00264                                                             rhs.clone())); 
00265   }
00266   
00267   
00269   template <typename CellType, typename InterfaceType>
00270   viennamath::rt_expr<InterfaceType> operator*(viennamath::rt_expr<InterfaceType> const & lhs,
00271                                                cell_quan<CellType, InterfaceType> const & rhs)
00272   {
00273     return viennamath::rt_expr<InterfaceType>(new viennamath::rt_binary_expr<InterfaceType>(lhs.get()->clone(),
00274                                                             new viennamath::op_binary<viennamath::op_mult<viennamath::default_numeric_type>, InterfaceType >(),
00275                                                             rhs.clone())); 
00276   }
00277   
00279   template <typename CellType, typename InterfaceType>
00280   viennamath::rt_expr<InterfaceType> operator*(cell_quan<CellType, InterfaceType> const & lhs,
00281                                                viennamath::rt_unary_expr<InterfaceType> const & rhs
00282                                )
00283   {
00284     return viennamath::rt_expr<InterfaceType>(new viennamath::rt_binary_expr<InterfaceType>(lhs.clone(),
00285                                                             new viennamath::op_binary<viennamath::op_mult<viennamath::default_numeric_type>, InterfaceType >(),
00286                                                             rhs.clone())); 
00287   }
00288 
00290   template <typename CellType, typename InterfaceType>
00291   viennamath::rt_expr<InterfaceType> operator*(cell_quan<CellType, InterfaceType> const & lhs,
00292                                                viennamath::rt_binary_expr<InterfaceType> const & rhs
00293                                )
00294   {
00295     return viennamath::rt_expr<InterfaceType>(new viennamath::rt_binary_expr<InterfaceType>(lhs.clone(),
00296                                                             new viennamath::op_binary<viennamath::op_mult<viennamath::default_numeric_type>, InterfaceType >(),
00297                                                             rhs.clone())); 
00298   }
00299 
00300 }
00301 #endif

Generated on Wed Feb 29 2012 21:51:05 for ViennaFEM - The Vienna Finite Element Method Library by  doxygen 1.7.1