FemKernel.hpp

00001 // This file is part of the imaging2 class library.
00002 //
00003 // University of Innsbruck, Infmath Imaging, 2009.
00004 // http://infmath.uibk.ac.at
00005 //
00006 // All rights reserved.
00007 
00008 
00009 #ifndef FEM_FEMKERNEL_H
00010 #define FEM_FEMKERNEL_H
00011 
00012 #include <core/imaging2.hpp>
00013 #include <core/matrix_utilities.hpp>
00014 
00015 namespace imaging
00016 {
00017 
00018   template<class fem_types> class Grid;
00019 
00020   template<std::size_t M, std::size_t N>
00021   float_t transform_det(const ublas::fixed_matrix<float_t, M, N> & derivative)
00022   {
00023     return fabs(determinant(derivative));
00024   }
00025 
00035   template<class fem_types>
00036   class FemKernel
00037   {
00038   private:
00039     static const std::size_t data_dimension = fem_types::data_dimension;
00040 
00041     static const std::size_t n_element_nodes = fem_types::shape_function_t::n_element_nodes;
00042     static const std::size_t n_element_vertices = fem_types::transform_t::n_element_vertices;
00043 
00044     typedef typename fem_types::shape_function_t shape_function_t;
00045 
00046     typedef typename fem_types::transform_t transform_t;
00047     typedef typename fem_types::integrator_t integrator_t;
00048     typedef typename fem_types::boundary_integrator_t boundary_integrator_t;
00049     
00050     ublas::fixed_vector< ublas::fixed_vector<float_t, n_element_nodes>, integrator_t::n_nodes> _shape_values;
00051     ublas::fixed_vector< ublas::fixed_vector< ublas::fixed_vector<float_t, data_dimension>, n_element_nodes >, integrator_t::n_nodes > _shape_gradients;
00052     ublas::fixed_vector<float_t, integrator_t::n_nodes> _transform_determinants;
00053 
00054     ublas::fixed_vector< ublas::fixed_vector<float_t, n_element_nodes>, boundary_integrator_t::n_nodes > _shape_boundary_values;
00055     ublas::fixed_vector< ublas::fixed_vector<float_t, n_element_nodes>, boundary_integrator_t::n_nodes > _shape_boundary_derivatives;
00056     ublas::fixed_vector<float_t, boundary_integrator_t::n_nodes> _boundary_transform_determinants;
00057     
00058     ublas::fixed_vector<float_t, data_dimension> _boundary_normal;
00059     ublas::fixed_vector< ublas::fixed_vector<float_t, data_dimension>, shape_function_t::n_shape_face_nodes > _boundary_normals_at_nodes;
00060     
00061 
00062     const Grid<fem_types> & _grid;
00063     std::size_t _current_element;
00064     std::size_t _current_boundary_element;
00065 
00066   public:
00067 
00069     FemKernel(const Grid<fem_types> & grid) : _grid(grid) {}
00070 
00072     const Grid<fem_types> & grid() const { return _grid; };
00073     
00079     void set_element(std::size_t element);
00080     
00086     void set_boundary_element(std::size_t boundary_element);
00087 
00090     void lazy_set_element(std::size_t element) { _current_element = element; }
00091 
00093     float_t shape_value(std::size_t integrator_node, std::size_t element_node) const
00094       { return _shape_values(integrator_node)(element_node); }
00095     
00097     const ublas::fixed_vector<float_t, fem_types::data_dimension> & shape_gradient(std::size_t integrator_node, std::size_t element_node) const
00098       { return _shape_gradients(integrator_node)(element_node); }
00099     
00101     float_t transform_determinant(std::size_t integrator_node) const
00102       { return _transform_determinants(integrator_node); }
00103   
00105     float_t shape_boundary_value(std::size_t integrator_node, std::size_t element_node) const
00106       { return _shape_boundary_values(integrator_node)(element_node); }
00107 
00109     float_t shape_boundary_derivative(std::size_t integrator_node, std::size_t element_node) const
00110       { return _shape_boundary_derivatives(integrator_node)(element_node); }
00111 
00113     float_t boundary_transform_determinant(std::size_t integrator_node) const
00114       { return _boundary_transform_determinants(integrator_node); }
00115       
00117     const ublas::fixed_vector<float_t, fem_types::data_dimension> & boundary_normal() const
00118       { return _boundary_normal; }
00119 
00121     std::size_t current_element() const { return _current_element; }
00122     
00124     std::size_t current_boundary_element() const { return _current_boundary_element; }
00125     
00127     bool is_boundary_node(std::size_t element_node) const { return _grid.is_boundary_node(_current_element,element_node); }
00128     
00130     const ublas::fixed_vector<float_t, fem_types::data_dimension> boundary_normal_at_node(std::size_t element_node) const { return _grid.boundary_normal(_current_element, element_node); }
00131   }
00132   ;
00133 
00134   template <class fem_types>
00135   void FemKernel<fem_types>::set_element(std::size_t element)
00136   {
00137     transform_t transform;
00138     shape_function_t shape_function;
00139     integrator_t integrator;
00140 
00141     _current_element = element;
00142 
00143     _grid.element_transform(element, transform);
00144 
00145     for(std::size_t integrator_node = 0; integrator_node < integrator_t::n_nodes; ++integrator_node)
00146     {
00147       ublas::fixed_matrix<float_t, data_dimension, data_dimension> derivative, inverse_derivative;
00148       ublas::fixed_vector<float_t, data_dimension> temp;
00149 
00150       transform.derivative(integrator.node(integrator_node), derivative);
00151       inverse_derivative = inverse(derivative);
00152 
00153       _transform_determinants(integrator_node) = transform_det(derivative);
00154 
00155       for(std::size_t element_node = 0; element_node < n_element_nodes; ++element_node)
00156       {
00157         _shape_values(integrator_node)(element_node) = shape_function.value(element_node, integrator.node(integrator_node));
00158         shape_function.gradient(element_node, integrator.node(integrator_node), temp);
00159         _shape_gradients(integrator_node)(element_node) = prod(temp, inverse_derivative);
00160       }
00161     }
00162 
00163   }
00164 
00165 
00166 
00167   template <class fem_types>
00168   void FemKernel<fem_types>::set_boundary_element(std::size_t element)
00169   {
00170     transform_t transform;
00171     shape_function_t shape_function;
00172     boundary_integrator_t integrator;
00173     std::size_t parent_element = _grid.parent_element(element);
00174     std::size_t parent_element_face = _grid.parent_element_face(element);
00175 
00176     _current_boundary_element = element;
00177 
00178     _grid.element_transform(parent_element, transform);
00179 
00180     transform.boundary_normal(parent_element_face, _boundary_normal);
00181     
00182     for(std::size_t integrator_node = 0; integrator_node < boundary_integrator_t::n_nodes; ++integrator_node)
00183     {
00184       ublas::fixed_matrix<float_t, data_dimension, data_dimension> derivative, inverse_derivative;
00185       ublas::fixed_matrix<float_t, data_dimension, data_dimension - 1> boundary_transform_derivative;
00186       ublas::fixed_vector<float_t, data_dimension> element_coordinates, gradient, boundary_normal, transformed_boundary_normal, temp;
00187       
00188       transform.boundary2element(parent_element_face, integrator.node(integrator_node), element_coordinates);
00189 
00190       transform.derivative(element_coordinates, derivative);
00191       inverse_derivative = inverse(derivative);
00192       transform.boundary_derivative(parent_element_face, integrator.node(integrator_node), boundary_transform_derivative);
00193       
00194       _boundary_transform_determinants(integrator_node) = transform_det(boundary_transform_derivative);
00195 
00196       for(std::size_t element_node = 0; element_node < n_element_nodes; ++element_node)
00197       {
00198         _shape_boundary_values(integrator_node)(element_node) =
00199           shape_function.value(element_node, element_coordinates);
00200 
00201         shape_function.gradient(element_node, element_coordinates, temp);
00202         gradient = prod(temp, inverse_derivative);
00203 
00204         _shape_boundary_derivatives(integrator_node)(element_node) = inner_prod(gradient, transformed_boundary_normal);
00205       }
00206     }
00207   }
00208   
00209   template <>
00210   float_t transform_det(const ublas::fixed_matrix<float_t, 1, 0> & derivative);
00211 
00212   template <>
00213   float_t transform_det(const ublas::fixed_matrix<float_t, 1, 1> & derivative);
00214    
00215   template <>
00216   float_t transform_det(const ublas::fixed_matrix<float_t, 2, 1> & derivative);
00217    
00218   template <>
00219   float_t transform_det(const ublas::fixed_matrix<float_t, 3, 2> & derivative);
00220 
00221 }
00222 
00223 
00224 #endif

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