McmStep.hpp

00001 #ifndef EQUATION_MCMSTEP_H
00002 #define EQUATION_MCMSTEP_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 McmStep : public SimpleEquationInterface<fem_types>
00020   {
00021     boost::shared_ptr< ublas::vector<float_t> > _input_ptr;
00022     float_t _epsilon;
00023     float_t _step_size;
00024     
00025     float_t regularized_abs(const ublas::fixed_vector<float_t, fem_types::data_dimension > & vector) const
00026     {
00027       return sqrt(square(_epsilon) + inner_prod(vector, vector));
00028     }
00029 
00030   public:
00031     typedef ublas::fixed_matrix<float_t, fem_types::data_dimension, fem_types::data_dimension> matrix_coefficient_t;
00032     typedef typename ublas::fixed_vector<float_t, fem_types::data_dimension> vector_coefficient_t;
00033 
00034     McmStep() : _step_size(0.0), _epsilon(1.0) {}
00035 
00037     const ublas::vector<float_t> & input() const { return *_input_ptr; }
00038     
00040     void set_input(boost::shared_ptr< ublas::vector<float_t> > input_ptr) { _input_ptr = input_ptr; }
00041     
00043     float_t step_size() const { return _step_size; }
00044     
00046     void set_step_size(float_t step_size) { _step_size = step_size; }
00047 
00049     float_t epsilon() const {return _epsilon; }
00050 
00052     void set_epsilon(float_t epsilon) { _epsilon = epsilon; }
00053 
00054     static const bool a_active = false;
00055     static const bool b_active = false;
00056     static const bool c_active = true;
00057     static const bool f_active = true;
00058     static const bool g_active = false;
00059     
00060     static const size_t boundary_data_type = SimpleEquationInterface<fem_types>::NO_BOUNDARY_DATA;  
00061 
00062     void stiffness_matrix(std::size_t integrator_node,
00063                           const FemKernel<fem_types> & kernel,
00064                           matrix_coefficient_t & A,
00065                           ublas::fixed_vector<float_t, fem_types::data_dimension> & a,
00066                           ublas::fixed_vector<float_t, fem_types::data_dimension> & b,
00067                           float_t & c) const
00068     {
00069       ublas::fixed_vector <float_t, fem_types::data_dimension> local_gradient;
00070       kernel.grid().interpolate_gradient(integrator_node, *_input_ptr, kernel, local_gradient);
00071       
00072       float_t regularized_abs_gradient = regularized_abs(local_gradient);
00073       A = _step_size / regularized_abs_gradient * ublas::identity_matrix<float_t>(fem_types::data_dimension);
00074       c = 1.0 / regularized_abs_gradient;
00075     }
00076 
00077     void force_vector(std::size_t integrator_node,
00078                       const FemKernel<fem_types> & kernel,
00079                       float_t & f,
00080                       ublas::fixed_vector<float_t, fem_types::data_dimension> & g) const
00081     { 
00082       float_t local_input;
00083       kernel.grid().interpolate_value(integrator_node, *_input_ptr, kernel, local_input);
00084 
00085       ublas::fixed_vector <float_t, fem_types::data_dimension> local_gradient;
00086       kernel.grid().interpolate_gradient(integrator_node, *_input_ptr, kernel, local_gradient);
00087 
00088       f = local_input / regularized_abs(local_gradient);
00089     }
00090     
00091     bool sanity_check_stiffness_matrix(const FemKernel<fem_types> & kernel, std::string & error_message) const
00092     { 
00093       if(! _input_ptr)
00094         return false;
00095         
00096       if(_input_ptr->size() != kernel.grid().n_nodes())
00097         return false;
00098         
00099       return true;
00100     }
00101     
00102     bool sanity_check_force_vector(const FemKernel<fem_types> & kernel, std::string & error_message) const
00103     { 
00104       if(! _input_ptr)
00105         return false;
00106         
00107       if(_input_ptr->size() != kernel.grid().n_nodes())
00108         return false;
00109         
00110       return true;
00111     }
00112 
00113   };
00114 
00115 }
00116 
00117 
00118 #endif

Generated on Tue Feb 10 10:01:30 2009 for imaging2 by  doxygen 1.5.5