$extrastylesheet
fem_context.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_FEM_CONTEXT_H
00021 #define LIBMESH_FEM_CONTEXT_H
00022 
00023 // Local Includes
00024 #include "libmesh/diff_context.h"
00025 #include "libmesh/id_types.h"
00026 #include "libmesh/fe_type.h"
00027 #include "libmesh/fe_base.h"
00028 #include "libmesh/vector_value.h"
00029 
00030 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00031 #include "libmesh/tensor_value.h"
00032 #endif
00033 
00034 // C++ includes
00035 #include <map>
00036 
00037 namespace libMesh
00038 {
00039 
00040 // Forward Declarations
00041 class BoundaryInfo;
00042 class Elem;
00043 template <typename T> class FEGenericBase;
00044 typedef FEGenericBase<Real> FEBase;
00045 class QBase;
00046 class Point;
00047 template <typename T> class NumericVector;
00048 
00061 // ------------------------------------------------------------
00062 // FEMContext class definition
00063 
00064 class FEMContext : public DiffContext
00065 {
00066 public:
00067 
00071   explicit
00072   FEMContext (const System &sys);
00073 
00077   virtual ~FEMContext ();
00078 
00082   bool has_side_boundary_id(boundary_id_type id) const;
00083 
00087   std::vector<boundary_id_type> side_boundary_ids() const;
00088 
00094   Number interior_value(unsigned int var, unsigned int qp) const;
00095 
00101   Number side_value(unsigned int var, unsigned int qp) const;
00102 
00108   Number point_value(unsigned int var, const Point &p) const;
00109 
00115   Gradient interior_gradient(unsigned int var, unsigned int qp) const;
00116 
00122   Gradient side_gradient(unsigned int var, unsigned int qp) const;
00123 
00129   Gradient point_gradient(unsigned int var, const Point &p) const;
00130 
00131 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00132 
00137   Tensor interior_hessian(unsigned int var, unsigned int qp) const;
00138 
00144   Tensor side_hessian(unsigned int var, unsigned int qp) const;
00145 
00151   Tensor point_hessian(unsigned int var, const Point &p) const;
00152 
00153 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
00154 
00160   Number fixed_interior_value(unsigned int var, unsigned int qp) const;
00161 
00167   Number fixed_side_value(unsigned int var, unsigned int qp) const;
00168 
00174   Number fixed_point_value(unsigned int var, const Point &p) const;
00175 
00181   Gradient fixed_interior_gradient(unsigned int var, unsigned int qp) const;
00182 
00188   Gradient fixed_side_gradient(unsigned int var, unsigned int qp) const;
00189 
00195   Gradient fixed_point_gradient(unsigned int var, const Point &p) const;
00196 
00197 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00198 
00203   Tensor fixed_interior_hessian(unsigned int var, unsigned int qp) const;
00204 
00210   Tensor fixed_side_hessian(unsigned int var, unsigned int qp) const;
00211 
00217   Tensor fixed_point_hessian (unsigned int var, const Point &p) const;
00218 
00219 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
00220 
00227   template<typename OutputShape>
00228   void get_element_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const
00229   { this->get_element_fe<OutputShape>(var,fe,this->get_dim()); }
00230 
00237   FEBase* get_element_fe( unsigned int var ) const
00238   { return this->get_element_fe(var,this->get_dim()); }
00239 
00244   template<typename OutputShape>
00245   void get_element_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
00246                        unsigned char dim ) const;
00247 
00252   FEBase* get_element_fe( unsigned int var, unsigned char dim ) const;
00253 
00260   template<typename OutputShape>
00261   void get_side_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const
00262   { this->get_side_fe<OutputShape>(var,fe,this->get_dim()); }
00263 
00270   FEBase* get_side_fe( unsigned int var ) const
00271   { return this->get_side_fe(var,this->get_dim()); }
00272 
00277   template<typename OutputShape>
00278   void get_side_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
00279                     unsigned char dim ) const;
00280 
00285   FEBase* get_side_fe( unsigned int var, unsigned char dim ) const;
00286 
00290   template<typename OutputShape>
00291   void get_edge_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const;
00292 
00296   FEBase* get_edge_fe( unsigned int var ) const;
00297 
00302   template<typename OutputType>
00303   void interior_value(unsigned int var, unsigned int qp,
00304                       OutputType& u) const;
00305 
00310   template<typename OutputType>
00311   void interior_values(unsigned int var, const NumericVector<Number> & _system_vector,
00312                        std::vector<OutputType>& interior_values_vector) const;
00313 
00318   template<typename OutputType>
00319   void side_value(unsigned int var, unsigned int qp,
00320                   OutputType& u) const;
00321 
00326   template<typename OutputType>
00327   void side_values(unsigned int var, const NumericVector<Number> & _system_vector,
00328                    std::vector<OutputType>& side_values_vector) const;
00329 
00334   template<typename OutputType>
00335   void point_value(unsigned int var, const Point &p,
00336                    OutputType& u) const;
00337 
00342   template<typename OutputType>
00343   void interior_gradient(unsigned int var, unsigned int qp,
00344                          OutputType& du) const;
00345 
00350   template<typename OutputType>
00351   void interior_gradients(unsigned int var, const NumericVector<Number> & _system_vector,
00352                           std::vector<OutputType>& interior_gradients_vector) const;
00353 
00358   template<typename OutputType>
00359   void side_gradient(unsigned int var, unsigned int qp,
00360                      OutputType & du) const;
00361 
00366   template<typename OutputType>
00367   void side_gradients(unsigned int var, const NumericVector<Number> & _system_vector,
00368                       std::vector<OutputType>& side_gradients_vector) const;
00369 
00374   template<typename OutputType>
00375   void point_gradient(unsigned int var, const Point &p,
00376                       OutputType& grad_u) const;
00377 
00378 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00379 
00383   template<typename OutputType>
00384   void interior_hessian(unsigned int var, unsigned int qp,
00385                         OutputType& d2u) const;
00386 
00392   template<typename OutputType>
00393   void interior_hessians(unsigned int var, const NumericVector<Number> & _system_vector,
00394                          std::vector<OutputType>& d2u_vals) const;
00395 
00400   template<typename OutputType>
00401   void side_hessian(unsigned int var, unsigned int qp,
00402                     OutputType& d2u) const;
00403 
00409   template<typename OutputType>
00410   void side_hessians(unsigned int var, const NumericVector<Number> & _system_vector,
00411                      std::vector<OutputType>& d2u_vals) const;
00412 
00417   template<typename OutputType>
00418   void point_hessian(unsigned int var, const Point &p,
00419                      OutputType& hess_u) const;
00420 
00421 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
00422 
00428   template<typename OutputType>
00429   void interior_rate(unsigned int var, unsigned int qp,
00430                      OutputType& u) const;
00431 
00436   template<typename OutputType>
00437   void side_rate(unsigned int var, unsigned int qp,
00438                  OutputType& u) const;
00439 
00444   template<typename OutputType>
00445   void point_rate(unsigned int var, const Point &p,
00446                   OutputType& u) const;
00447 
00452   template<typename OutputType>
00453   void fixed_interior_value(unsigned int var, unsigned int qp,
00454                             OutputType& u) const;
00455 
00460   template<typename OutputType>
00461   void fixed_side_value(unsigned int var, unsigned int qp,
00462                         OutputType& u) const;
00463 
00468   template<typename OutputType>
00469   void fixed_point_value(unsigned int var, const Point &p,
00470                          OutputType& u) const;
00471 
00476   template<typename OutputType>
00477   void fixed_interior_gradient(unsigned int var, unsigned int qp,
00478                                OutputType& grad_u) const;
00479 
00484   template<typename OutputType>
00485   void fixed_side_gradient(unsigned int var, unsigned int qp,
00486                            OutputType& grad_u) const;
00487 
00492   template<typename OutputType>
00493   void fixed_point_gradient(unsigned int var, const Point &p,
00494                             OutputType& grad_u) const;
00495 
00496 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00497 
00501   template<typename OutputType>
00502   void fixed_interior_hessian(unsigned int var, unsigned int qp,
00503                               OutputType& hess_u) const;
00504 
00509   template<typename OutputType>
00510   void fixed_side_hessian(unsigned int var, unsigned int qp,
00511                           OutputType& hess_u) const;
00512 
00517   template<typename OutputType>
00518   void fixed_point_hessian(unsigned int var, const Point &p,
00519                            OutputType& hess_u) const;
00520 
00521 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
00522 
00527   template<typename OutputType>
00528   void interior_curl(unsigned int var, unsigned int qp,
00529                      OutputType& curl_u) const;
00530 
00535   template<typename OutputType>
00536   void point_curl(unsigned int var, const Point &p,
00537                   OutputType& curl_u) const;
00538 
00543   template<typename OutputType>
00544   void interior_div(unsigned int var, unsigned int qp,
00545                     OutputType& div_u) const;
00546 
00551   //  virtual void reinit(const FEMSystem&, Elem*);
00552 
00553   // should be protected:
00559   virtual void elem_reinit(Real theta);
00560 
00566   virtual void elem_side_reinit(Real theta);
00567 
00573   virtual void elem_edge_reinit(Real theta);
00574 
00579   virtual void nonlocal_reinit(Real theta);
00580 
00584   virtual void pre_fe_reinit(const System&, const Elem *e);
00585 
00589   void elem_fe_reinit();
00590 
00594   virtual void side_fe_reinit();
00595 
00599   void edge_fe_reinit();
00600 
00605   const QBase& get_element_qrule() const
00606   { return this->get_element_qrule(this->get_elem_dim()); }
00607 
00612   const QBase& get_side_qrule() const
00613   { return this->get_side_qrule(this->get_elem_dim()); }
00614 
00618   const QBase& get_element_qrule( unsigned char dim ) const
00619   { libmesh_assert(_element_qrule[dim]);
00620     return *(this->_element_qrule[dim]); }
00621 
00625   const QBase& get_side_qrule( unsigned char dim ) const
00626   { libmesh_assert(_side_qrule[dim]);
00627     return *(this->_side_qrule[dim]); }
00628 
00632   const QBase& get_edge_qrule() const
00633   { return *(this->_edge_qrule); }
00634 
00643   virtual void set_mesh_system(System* sys)
00644   { this->_mesh_sys = sys; }
00645 
00649   const System* get_mesh_system() const
00650   { return this->_mesh_sys; }
00651 
00655   System* get_mesh_system()
00656   { return this->_mesh_sys; }
00657 
00661   unsigned int get_mesh_x_var() const
00662   { return _mesh_x_var; }
00663 
00669   void set_mesh_x_var(unsigned int x_var)
00670   { _mesh_x_var = x_var; }
00671 
00675   unsigned int get_mesh_y_var() const
00676   { return _mesh_y_var; }
00677 
00683   void set_mesh_y_var(unsigned int y_var)
00684   { _mesh_y_var = y_var; }
00685 
00689   unsigned int get_mesh_z_var() const
00690   { return _mesh_z_var; }
00691 
00697   void set_mesh_z_var(unsigned int z_var)
00698   { _mesh_z_var = z_var; }
00699 
00703   bool has_elem() const
00704   { return (this->_elem != NULL); }
00705 
00709   const Elem& get_elem() const
00710   { libmesh_assert(this->_elem);
00711     return *(this->_elem); }
00712 
00716   Elem& get_elem()
00717   { libmesh_assert(this->_elem);
00718     return *(const_cast<Elem*>(this->_elem)); }
00719 
00723   unsigned char get_side() const
00724   { return side; }
00725 
00729   unsigned char get_edge() const
00730   { return edge; }
00731 
00737   unsigned char get_dim() const
00738   { return this->_dim; }
00739 
00744   unsigned char get_elem_dim() const
00745   { return _elem_dim; }
00746 
00747 
00753   void elem_position_set(Real theta);
00754 
00759   void elem_position_get();
00760 
00764   System *_mesh_sys;
00765 
00769   unsigned int _mesh_x_var, _mesh_y_var, _mesh_z_var;
00770 
00774   unsigned char side;
00775 
00779   unsigned char edge;
00780 
00781 protected:
00782 
00786   template<typename OutputShape>
00787   UniquePtr<FEGenericBase<OutputShape> > build_new_fe( const FEGenericBase<OutputShape>* fe, const Point &p ) const;
00788 
00792   void set_elem( const Elem* e );
00793 
00794   // gcc-3.4, oracle 12.3 require this typedef to be public
00795   // in order to use it in a return type
00796 public:
00797 
00801   typedef const DenseSubVector<Number>& (DiffContext::*diff_subsolution_getter)(unsigned int) const;
00802 
00803 protected:
00808   template<typename OutputType,
00809            diff_subsolution_getter subsolution_getter>
00810   void some_interior_value(unsigned int var, unsigned int qp, OutputType& u) const;
00811 
00816   template<typename OutputType,
00817            diff_subsolution_getter subsolution_getter>
00818   void some_interior_gradient(unsigned int var, unsigned int qp, OutputType& u) const;
00819 
00820 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00821 
00825   template<typename OutputType,
00826            diff_subsolution_getter subsolution_getter>
00827   void some_interior_hessian(unsigned int var, unsigned int qp, OutputType& u) const;
00828 #endif
00829 
00834   template<typename OutputType,
00835            diff_subsolution_getter subsolution_getter>
00836   void some_side_value(unsigned int var, unsigned int qp, OutputType& u) const;
00837 
00838 
00844   std::vector<std::map<FEType, FEAbstract*> > _element_fe;
00845   std::vector<std::map<FEType, FEAbstract*> > _side_fe;
00846   std::map<FEType, FEAbstract*> _edge_fe;
00847 
00848 
00855   std::vector<std::vector<FEAbstract*> > _element_fe_var;
00856   std::vector<std::vector<FEAbstract*> > _side_fe_var;
00857   std::vector<FEAbstract*> _edge_fe_var;
00858 
00863   const BoundaryInfo& _boundary_info;
00864 
00868   const Elem *_elem;
00869 
00873   unsigned char _dim;
00874 
00878   unsigned char _elem_dim;
00879 
00886   std::vector<QBase*> _element_qrule;
00887 
00894   std::vector<QBase*> _side_qrule;
00895 
00903   QBase *_edge_qrule;
00904 
00905 private:
00914   void _do_elem_position_set(Real theta);
00915 
00921   void _update_time_from_system(Real theta);
00922 };
00923 
00924 
00925 
00926 // ------------------------------------------------------------
00927 // FEMContext inline methods
00928 
00929 inline
00930 void FEMContext::elem_position_set(Real theta)
00931 {
00932   if (_mesh_sys)
00933     this->_do_elem_position_set(theta);
00934 }
00935 
00936 template<typename OutputShape>
00937 inline
00938 void FEMContext::get_element_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
00939                                  unsigned char dim ) const
00940 {
00941   libmesh_assert( !_element_fe_var[dim].empty() );
00942   libmesh_assert_less ( var, (_element_fe_var[dim].size() ) );
00943   fe = cast_ptr<FEGenericBase<OutputShape>*>( (_element_fe_var[dim][var] ) );
00944 }
00945 
00946 inline
00947 FEBase* FEMContext::get_element_fe( unsigned int var, unsigned char dim ) const
00948 {
00949   libmesh_assert( !_element_fe_var[dim].empty() );
00950   libmesh_assert_less ( var, (_element_fe_var[dim].size() ) );
00951   return cast_ptr<FEBase*>( (_element_fe_var[dim][var] ) );
00952 }
00953 
00954 template<typename OutputShape>
00955 inline
00956 void FEMContext::get_side_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
00957                               unsigned char dim ) const
00958 {
00959   libmesh_assert( !_side_fe_var[dim].empty() );
00960   libmesh_assert_less ( var, (_side_fe_var[dim].size() ) );
00961   fe = cast_ptr<FEGenericBase<OutputShape>*>( (_side_fe_var[dim][var] ) );
00962 }
00963 
00964 inline
00965 FEBase* FEMContext::get_side_fe( unsigned int var, unsigned char dim ) const
00966 {
00967   libmesh_assert( !_side_fe_var[dim].empty() );
00968   libmesh_assert_less ( var, (_side_fe_var[dim].size() ) );
00969   return cast_ptr<FEBase*>( (_side_fe_var[dim][var] ) );
00970 }
00971 
00972 template<typename OutputShape>
00973 inline
00974 void FEMContext::get_edge_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const
00975 {
00976   libmesh_assert_less ( var, _edge_fe_var.size() );
00977   fe = cast_ptr<FEGenericBase<OutputShape>*>( _edge_fe_var[var] );
00978 }
00979 
00980 inline
00981 FEBase* FEMContext::get_edge_fe( unsigned int var ) const
00982 {
00983   libmesh_assert_less ( var, _edge_fe_var.size() );
00984   return cast_ptr<FEBase*>( _edge_fe_var[var] );
00985 }
00986 
00987 
00988 } // namespace libMesh
00989 
00990 #endif // LIBMESH_FEM_CONTEXT_H