00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EQUATION_DIFFUSIONSTEP_H
00011 #define EQUATION_DIFFUSIONSTEP_H
00012
00013 #include <fem/equation/SimpleEquationInterface.hpp>
00014 #include <boost/shared_ptr.hpp>
00015
00016
00017 namespace imaging
00018 {
00028 template<class fem_types>
00029 class DiffusionStep : public SimpleEquationInterface<fem_types>
00030 {
00031 boost::shared_ptr< ublas::vector<float_t> > _input_ptr;
00032 boost::shared_ptr< ublas::vector<float_t> > _diffusion_ptr;
00033 float_t _step_size;
00034
00035 public:
00036 typedef ublas::fixed_matrix<float_t, fem_types::data_dimension, fem_types::data_dimension> matrix_coefficient_t;
00037 typedef typename ublas::fixed_vector<float_t, fem_types::data_dimension> vector_coefficient_t;
00038
00039 DiffusionStep() : _step_size(0.0) {}
00040
00042 const ublas::vector<float_t> & input() const { return *_input_ptr; }
00043
00045 void set_input(boost::shared_ptr< ublas::vector<float_t> > input_ptr) { _input_ptr = input_ptr; }
00046
00048 const ublas::vector<float_t> & diffusion() const { return *_diffusion_ptr; }
00049
00051 void set_diffusion(boost::shared_ptr< ublas::vector<float_t> > diffusion_ptr) { _diffusion_ptr = diffusion_ptr; }
00052
00054 float_t step_size() const { return _step_size; }
00055
00057 void set_step_size(float_t step_size) { _step_size = step_size; }
00058
00059 static const size_t boundary_data_type = SimpleEquationInterface<fem_types>::NO_BOUNDARY_DATA;
00060
00061 static const bool a_active = false;
00062 static const bool b_active = false;
00063 static const bool c_active = true;
00064 static const bool f_active = true;
00065 static const bool g_active = false;
00066
00067 void stiffness_matrix(std::size_t integrator_node,
00068 const FemKernel<fem_types> & kernel,
00069 matrix_coefficient_t & A,
00070 ublas::fixed_vector<float_t, fem_types::data_dimension> & a,
00071 ublas::fixed_vector<float_t, fem_types::data_dimension> & b,
00072 float_t & c) const
00073 {
00074 float_t local_diffusion;
00075 kernel.grid().interpolate_value(integrator_node, *_diffusion_ptr, kernel, local_diffusion);
00076 A = _step_size * local_diffusion * ublas::identity_matrix<float_t>(fem_types::data_dimension);
00077 c = 1.0;
00078 }
00079
00080 void force_vector(std::size_t integrator_node,
00081 const FemKernel<fem_types> & kernel,
00082 float_t & f,
00083 ublas::fixed_vector<float_t, fem_types::data_dimension> & g) const
00084 {
00085 kernel.grid().interpolate_value(integrator_node, *_input_ptr, kernel, f);
00086 }
00087
00088 bool sanity_check_stiffness_matrix(const FemKernel<fem_types> & kernel, std::string & error_message) const
00089 {
00090 if(! _diffusion_ptr)
00091 return false;
00092
00093 if(_diffusion_ptr->size() != kernel.grid().n_nodes())
00094 return false;
00095
00096 return true;
00097 }
00098
00099 bool sanity_check_force_vector(const FemKernel<fem_types> & kernel, std::string & error_message) const
00100 {
00101 if(! _input_ptr)
00102 return false;
00103
00104 if(_input_ptr->size() != kernel.grid().n_nodes())
00105 return false;
00106
00107 return true;
00108 }
00109 };
00110
00111 }
00112
00113
00114 #endif