$extrastylesheet
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