00001 #ifndef EQUATION_TVFLOWSTEP_H
00002 #define EQUATION_TVFLOWSTEP_H
00003
00004 #include <fem/equation/SimpleEquationInterface.hpp>
00005 #include <boost/shared_ptr.hpp>
00006
00007 namespace imaging
00008 {
00018 template<class fem_types>
00019 class TvFlowStep: public SimpleEquationInterface<fem_types>
00020 {
00021 boost::shared_ptr< ublas::vector<float_t> > _input_ptr;
00022 float_t _step_size;
00023 float_t _epsilon;
00024
00025 public:
00026 typedef ublas::fixed_matrix<float_t, fem_types::data_dimension, fem_types::data_dimension> matrix_coefficient_t;
00027 typedef typename ublas::fixed_vector<float_t, fem_types::data_dimension> vector_coefficient_t;
00028
00029 TvFlowStep() : _step_size(0.0), _epsilon(1.0) {}
00030
00032 const ublas::vector<float_t> & input() const { return *_input_ptr; }
00033
00035 void set_input(boost::shared_ptr< ublas::vector<float_t> > input_ptr) { _input_ptr = input_ptr; }
00036
00038 float_t step_size() const { return _step_size; }
00039
00041 void set_step_size(float_t step_size) { _step_size = step_size; }
00042
00044 float_t epsilon() const { return _epsilon; }
00045
00047 void set_epsilon(float_t epsilon) { _epsilon = epsilon; }
00048
00049 static const bool a_active = false;
00050 static const bool b_active = false;
00051 static const bool c_active = true;
00052 static const bool f_active = true;
00053 static const bool g_active = false;
00054
00055 static const size_t boundary_data_type = SimpleEquationInterface<fem_types>::NO_BOUNDARY_DATA;
00056
00057 void stiffness_matrix(std::size_t integrator_node,
00058 const FemKernel<fem_types> & kernel,
00059 matrix_coefficient_t & A,
00060 ublas::fixed_vector<float_t, fem_types::data_dimension> & a,
00061 ublas::fixed_vector<float_t, fem_types::data_dimension> & b,
00062 float_t & c) const
00063 {
00064 ublas::fixed_vector<float_t, fem_types::data_dimension> local_gradient;
00065 kernel.grid().interpolate_gradient(integrator_node, *_input_ptr, kernel, local_gradient);
00066 A = _step_size / sqrt(inner_prod(local_gradient, local_gradient) + square(_epsilon)) *
00067 ublas::identity_matrix<float_t>(fem_types::data_dimension);
00068 c = 1.0;
00069 }
00070
00071 void force_vector(std::size_t integrator_node,
00072 const FemKernel<fem_types> & kernel,
00073 float_t & f,
00074 ublas::fixed_vector<float_t, fem_types::data_dimension> & g) const
00075 {
00076 kernel.grid().interpolate_value(integrator_node, *_input_ptr, kernel, f);
00077 }
00078
00079 bool sanity_check_stiffness_matrix(const FemKernel<fem_types> & kernel, std::string & error_message) const
00080 {
00081 if(! _input_ptr)
00082 return false;
00083
00084 if(_input_ptr->size() != kernel.grid().n_nodes())
00085 return false;
00086
00087 return true;
00088 }
00089
00090 bool sanity_check_force_vector(const FemKernel<fem_types> & kernel, std::string & error_message) const
00091 {
00092 if(! _input_ptr)
00093 return false;
00094
00095 if(_input_ptr->size() != kernel.grid().n_nodes())
00096 return false;
00097
00098 return true;
00099 }
00100
00101 };
00102
00103 }
00104
00105
00106 #endif