00001 #ifndef VIENNAFEM_CELL_QUAN_HPP
00002 #define VIENNAFEM_CELL_QUAN_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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 }
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
00169
00170
00171 explicit cell_quan() : current_cell(NULL) {}
00172
00173
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
00205 for (std::size_t i=0; i<e.size(); ++i)
00206 if (deep_equal(e[i]))
00207 return repl[i]->clone();
00208
00209
00210 return clone();
00211 };
00212
00213 bool deep_equal(const InterfaceType * other) const
00214 {
00215
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
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
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