00001 #ifndef EQUATION_POISSONEQUATION_H
00002 #define EQUATION_POISSONEQUATION_H
00003
00004 #include <fem/equation/SimpleEquationInterface.hpp>
00005
00006 namespace imaging
00007 {
00018 template<class fem_types>
00019 class PoissonEquation : public SimpleEquationInterface<fem_types>
00020 {
00021 boost::shared_ptr< ublas::vector<float_t> > _rhs_ptr;
00022 boost::shared_ptr< ublas::mapped_vector<float_t> > _boundary_data_ptr;
00023
00024 public:
00025 typedef ublas::fixed_matrix<float_t, fem_types::data_dimension, fem_types::data_dimension> matrix_coefficient_t;
00026
00028 const ublas::vector<float_t> & force() const { return *_rhs_ptr; }
00029
00031 void set_force(boost::shared_ptr< ublas::vector<float_t> > rhs_ptr) { _rhs_ptr = rhs_ptr; }
00032
00034 const ublas::mapped_vector<float_t> & boundary_data() const { return *_boundary_data_ptr; }
00035
00037 void set_boundary_data(boost::shared_ptr< ublas::mapped_vector<float_t> > boundary_data_ptr) { _boundary_data_ptr = boundary_data_ptr; }
00038
00039 static const size_t boundary_data_type = SimpleEquationInterface<fem_types>::DIRICHLET_DATA;
00040
00041 static const bool a_active = false;
00042 static const bool b_active = false;
00043 static const bool c_active = false;
00044 static const bool f_active = true;
00045 static const bool g_active = false;
00046
00047 void stiffness_matrix(std::size_t integrator_node,
00048 const FemKernel<fem_types> & kernel,
00049 matrix_coefficient_t & A,
00050 ublas::fixed_vector<float_t, fem_types::data_dimension> & a,
00051 ublas::fixed_vector<float_t, fem_types::data_dimension> & b,
00052 float_t & c) const
00053 {
00054 A = ublas::identity_matrix<float_t>(fem_types::data_dimension);
00055 }
00056
00057 void force_vector(std::size_t integrator_node,
00058 const FemKernel<fem_types> & kernel,
00059 float_t & f,
00060 ublas::fixed_vector<float_t, fem_types::data_dimension> & g) const
00061 {
00062 kernel.grid().interpolate_value(integrator_node, * _rhs_ptr, kernel, f);
00063 }
00064
00065 void force_vector_at_boundary (std::size_t integrator_node,
00066 const FemKernel< fem_types > & kernel,
00067 float_t & v) const
00068 {
00069 kernel.grid().interpolate_boundary_value(integrator_node, * _boundary_data_ptr, kernel, v);
00070 }
00071
00072 bool sanity_check_stiffness_matrix(const FemKernel<fem_types> & kernel, std::string & error_message) const
00073 {
00074 return true;
00075 }
00076
00077 bool sanity_check_force_vector(const FemKernel<fem_types> & kernel, std::string & error_message) const
00078 {
00079 if(! (_rhs_ptr && _boundary_data_ptr))
00080 return true;
00081
00082 if(_rhs_ptr->size() != kernel.grid().n_nodes())
00083 return false;
00084
00085 if(_boundary_data_ptr->size() != kernel.grid().n_nodes())
00086 return false;
00087
00088 return true;
00089 }
00090
00091 };
00092 }
00093
00094
00095 #endif